Ho provato a cercare su Internet ma non sono riuscito a trovare il significato di hash.
Quando dicono che gli oggetti sono hashable
o hashable objects
cosa significano?
Ho provato a cercare su Internet ma non sono riuscito a trovare il significato di hash.
Quando dicono che gli oggetti sono hashable
o hashable objects
cosa significano?
Risposte:
Dal glossario di Python :
Un oggetto è hash se ha un valore hash che non cambia mai durante il suo ciclo di vita (ha bisogno di un
__hash__()
metodo) e può essere confrontato con altri oggetti (ha bisogno di un metodo__eq__()
o__cmp__()
). Gli oggetti hash che si equivalgono devono avere lo stesso valore hash.La hashability rende un oggetto utilizzabile come chiave di dizionario e membro set, poiché queste strutture di dati utilizzano internamente il valore di hash.
Tutti gli oggetti incorporati immutabili di Python sono hash, mentre non esistono contenitori mutabili (come elenchi o dizionari). Gli oggetti che sono istanze di classi definite dall'utente sono hash per impostazione predefinita; si confrontano tutti in modo diseguale e il loro valore di hash è il loro
id()
.
hash value
ora qual è il valore di hash. puoi fare qualche esempio
__hash__()
. Più in generale, vedi en.wikipedia.org/wiki/Hash_function
id(object)
è 16x il risultato di object.__hash__()
. Quindi l'estratto di glossario non è corretto per questa versione - il valore di hash non id()
lo è, ma ne deriva (come notato nei documenti aggiornati per Python 2.7.12).
hash((1, [2, 3]))
a vederlo in azione. Ho pubblicato una richiesta per correggere la voce del glossario per hash.
Tutte le risposte qui hanno una buona spiegazione funzionante degli oggetti hash in Python, ma credo che si debba prima capire il termine Hashing.
L'hashing è un concetto di informatica che viene utilizzato per creare strutture di dati ad accesso pseudo casuale ad alte prestazioni in cui è necessario archiviare e accedere rapidamente a grandi quantità di dati.
Ad esempio, se si dispone di 10.000 numeri di telefono e si desidera archiviarli in un array (che è una struttura di dati sequenziale che archivia i dati in posizioni di memoria contigue e fornisce accesso casuale), ma è possibile che non si disponga della quantità richiesta di contigua posizioni di memoria.
Pertanto, puoi invece utilizzare un array di dimensioni 100 e utilizzare una funzione hash per mappare un set di valori sugli stessi indici e questi valori possono essere memorizzati in un elenco collegato. Ciò fornisce prestazioni simili a un array.
Ora, una funzione di hash può essere semplice come dividere il numero con la dimensione dell'array e prendere il resto come indice.
Per maggiori dettagli, consultare https://en.wikipedia.org/wiki/Hash_function
Ecco un altro buon riferimento: http://interactivepython.org/runestone/static/pythonds/SortSearch/Hashing.html
Tutto ciò che non è mutabile (mezzi mutabili, suscettibili di cambiare) può essere sottoposto a hash. Oltre alla funzione hash da cercare, se una classe ce l'ha, ad es. dir(tuple)
e cercando il __hash__
metodo, ecco alcuni esempi
#x = hash(set([1,2])) #set unhashable
x = hash(frozenset([1,2])) #hashable
#x = hash(([1,2], [2,3])) #tuple of mutable objects, unhashable
x = hash((1,2,3)) #tuple of immutable objects, hashable
#x = hash()
#x = hash({1,2}) #list of mutable objects, unhashable
#x = hash([1,2,3]) #list of immutable objects, unhashable
Elenco di tipi immutabili:
int, float, decimal, complex, bool, string, tuple, range, frozenset, bytes
Elenco di tipi mutabili:
list, dict, set, bytearray, user-defined classes
Ellipsis
è anche un tipo immutabile e può essere usato come chiave per a dict
.
hash(MyClass)
__hash__
e __eq__
. Inoltre, tutte le classi definite dall'utente implementano questi metodi (e quindi sono hash), perché ereditano i metodi dalla object
(classe base universale).
Secondo la mia comprensione secondo il glossario di Python, quando si crea un'istanza di oggetti che sono hash, viene anche calcolato un valore immutabile in base ai membri o ai valori dell'istanza. Ad esempio, quel valore potrebbe quindi essere utilizzato come chiave in un dict come di seguito:
>>> tuple_a = (1,2,3)
>>> tuple_a.__hash__()
2528502973977326415
>>> tuple_b = (2,3,4)
>>> tuple_b.__hash__()
3789705017596477050
>>> tuple_c = (1,2,3)
>>> tuple_c.__hash__()
2528502973977326415
>>> id(a) == id(c) # a and c same object?
False
>>> a.__hash__() == c.__hash__() # a and c same value?
True
>>> dict_a = {}
>>> dict_a[tuple_a] = 'hiahia'
>>> dict_a[tuple_c]
'hiahia'
possiamo scoprire che il valore di hash di tuple_a e tuple_c sono gli stessi poiché hanno gli stessi membri. Quando usiamo tuple_a come chiave in dict_a, possiamo scoprire che il valore per dict_a [tuple_c] è lo stesso, il che significa che, quando vengono utilizzati come chiave in un dict, restituiscono lo stesso valore perché i valori hash sono lo stesso. Per quegli oggetti che non sono hash, il metodo hash è definito come Nessuno:
>>> type(dict.__hash__)
<class 'NoneType'>
Immagino che questo valore di hash sia calcolato sull'inizializzazione dell'istanza, non in modo dinamico, ecco perché solo gli oggetti immutabili sono hash. Spero che questo ti aiuti.
Lascia che ti dia un esempio funzionante per comprendere gli oggetti hash in Python. Sto prendendo 2 tuple per questo esempio. Ogni valore in una tupla ha un valore hash univoco che non cambia mai durante la sua vita. Quindi sulla base di questo ha valore, viene fatto il confronto tra due tuple. Possiamo ottenere il valore hash di un elemento tupla usando Id ().
In Python significa che l'oggetto può essere membro di insiemi per restituire un indice. Cioè, hanno identità / ID univoci.
ad esempio, in Python 3.3:
la struttura dei dati Gli elenchi non sono eseguibili ma la struttura dei dati Le tuple sono eseguibili.
id
, che è (approssimativamente) l'indirizzo dell'oggetto in memoria.
Hashable = capace di essere hash.
Ok, cos'è l'hashing? Una funzione di hashing è una funzione che accetta un oggetto, ad esempio una stringa come "Python" e restituisce un codice di dimensioni fisse. Per semplicità, supponiamo che il valore restituito sia un numero intero.
Quando eseguo hash ('Python') in Python 3, ottengo 5952713340227947791 come risultato. Diverse versioni di Python sono libere di modificare la funzione hash sottostante, quindi probabilmente otterrai un valore diverso. L'importante è che non importa ora che eseguo hash ('Python'), otterrò sempre lo stesso risultato con la stessa versione di Python.
Ma hash ('Java') restituisce 1753925553814008565. Quindi se l'oggetto che sto eseguendo l'hashing cambia, anche il risultato cambia. D'altra parte, se l'oggetto con cui sto eseguendo il hashing non cambia, il risultato rimane lo stesso.
Perché è importante?
Bene, i dizionari Python, per esempio, richiedono che le chiavi siano immutabili. Cioè, le chiavi devono essere oggetti che non cambiano. Le stringhe sono immutabili in Python, così come gli altri tipi di base (int, float, bool). Anche le tuple e i frozenset sono immutabili. Le liste, d'altra parte, non sono immutabili (cioè sono mutabili) perché puoi cambiarle. Allo stesso modo, i dadi sono mutabili.
Quindi, quando diciamo che qualcosa è seccabile, intendiamo che è immutabile. Se provo a passare un tipo mutabile alla funzione hash (), fallirà:
>>> hash('Python')
1687380313081734297
>>> hash('Java')
1753925553814008565
>>>
>>> hash([1, 2])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> hash({1, 2})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'
>>> hash({1 : 2})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'dict'
>>>
>>> hash(frozenset({1, 2}))
-1834016341293975159
>>> hash((1, 2))
3713081631934410656
In Python, qualsiasi oggetto immutabile (come un numero intero, un valore booleano, una stringa, una tupla) è hash, il che significa che il suo valore non cambia durante la sua vita. Ciò consente a Python di creare un valore hash univoco per identificarlo, che può essere utilizzato dai dizionari per tenere traccia di chiavi e set univoci per tenere traccia di valori univoci.
Questo è il motivo per cui Python ci richiede di utilizzare tipi di dati immutabili per le chiavi in un dizionario.
Per creare una tabella di hashing da zero, tutti i valori devono essere impostati su "Nessuno" e modificati una volta che si presenta un requisito. Gli oggetti hashable si riferiscono ai tipi di dati modificabili (dizionario, elenchi ecc.). D'altra parte, i set non possono essere reinizializzati una volta assegnati, quindi i set non sono cancellabili. Considerando che, La variante di set () - frozenset () - è hash.
__hash__()
metodo .