Una delle strutture di dati di base in Python è il dizionario, che consente di registrare "chiavi" per cercare "valori" di qualsiasi tipo. Questo è implementato internamente come una tabella hash? Se no, cos'è?
Una delle strutture di dati di base in Python è il dizionario, che consente di registrare "chiavi" per cercare "valori" di qualsiasi tipo. Questo è implementato internamente come una tabella hash? Se no, cos'è?
Risposte:
Sì, è una mappatura hash o una tabella hash. Puoi leggere una descrizione dell'implementazione del dict di Python, come scritto da Tim Peters, qui .
Ecco perché non puoi usare qualcosa di "non cancellabile" come chiave dict, come un elenco:
>>> a = {}
>>> b = ['some', 'list']
>>> hash(b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable
>>> a[b] = 'some'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: list objects are unhashable
Puoi leggere di più sulle tabelle di hash o controllare come è stato implementato in Python e perché è implementato in quel modo .
.keys()
può recuperare un elenco di chiavi. Una vera tabella hash non memorizzava le chiavi, solo hash per risparmiare spazio.
In un dizionario Python deve esserci più di una ricerca di tabella su hash (). Con la sperimentazione brutale ho trovato questa collisione di hash :
>>> hash(1.1)
2040142438
>>> hash(4504.1)
2040142438
Eppure non rompe il dizionario:
>>> d = { 1.1: 'a', 4504.1: 'b' }
>>> d[1.1]
'a'
>>> d[4504.1]
'b'
Controllo sanitario:
>>> for k,v in d.items(): print(hash(k))
2040142438
2040142438
Forse c'è un altro livello di ricerca oltre hash () che evita le collisioni tra le chiavi del dizionario. O forse dict () usa un hash diverso.
(A proposito, questo in Python 2.7.10. Stessa storia in Python 3.4.3 e 3.5.0 con una collisione a hash(1.1) == hash(214748749.8)
.)
hash('I wandered lonely as a cloud, that drifts on high o\'er vales and hills, when all at once, I saw a crowd, a host of golden daffodils.')
Questo dà un decimale di 19 cifre - -4037225020714749784
se sei abbastanza geniale da preoccupartene. Continua con parole tue, figli, e l'hash è ancora un numero di 19 cifre. Suppongo che ci sia un limite alla lunghezza della stringa che puoi avere in Python, ma è sicuro di dire molte più stringhe possibili che possibili valori. E hash(False)
= 0 a proposito.
Sì. Internamente viene implementato come hash aperto basato su un polinomio primitivo su Z / 2 ( sorgente ).
Per espandere la spiegazione di nosklo:
a = {}
b = ['some', 'list']
a[b] = 'some' # this won't work
a[tuple(b)] = 'some' # this will, same as a['some', 'list']
dict
.