Una de las estructuras básicas de datos en Python es el diccionario, que permite registrar "claves" para buscar "valores" de cualquier tipo. ¿Se implementa esto internamente como una tabla hash? Si no, ¿qué es?
Una de las estructuras básicas de datos en Python es el diccionario, que permite registrar "claves" para buscar "valores" de cualquier tipo. ¿Se implementa esto internamente como una tabla hash? Si no, ¿qué es?
Respuestas:
Sí, es un mapeo hash o una tabla hash. Puede leer una descripción de la implementación dict de python, como está escrita por Tim Peters, aquí .
Es por eso que no puede usar algo 'no hashable' como clave dict, como una lista:
>>> 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
Puede leer más sobre las tablas hash o verificar cómo se ha implementado en python y por qué se implementa de esa manera .
.keys()
puede recuperar una lista de claves. Una tabla hash real no almacenaría claves, solo hashes para ahorrar espacio.
Debe haber más en un diccionario de Python que una búsqueda de tabla en hash (). Por experimentación bruta encontré esta colisión de hash :
>>> hash(1.1)
2040142438
>>> hash(4504.1)
2040142438
Sin embargo, no rompe el diccionario:
>>> d = { 1.1: 'a', 4504.1: 'b' }
>>> d[1.1]
'a'
>>> d[4504.1]
'b'
Prueba de cordura:
>>> for k,v in d.items(): print(hash(k))
2040142438
2040142438
Posiblemente hay otro nivel de búsqueda más allá de hash () que evita colisiones entre las teclas del diccionario. O tal vez dict () usa un hash diferente.
(Por cierto, esto en Python 2.7.10. La misma historia en Python 3.4.3 y 3.5.0 con una colisión en 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.')
Esto da un decimal de 19 dígitos, -4037225020714749784
si eres lo suficientemente geek como para preocuparte. Continúen con sus propias palabras, niños, y el hash sigue siendo un número de 19 dígitos. Supongo que hay un límite en la longitud de la cadena que puede hacer hash en Python, pero es seguro decir muchas más cadenas posibles que valores posibles. Y hash(False)
= 0 por cierto.
Si. Internamente se implementa como hashing abierto basado en un polinomio primitivo sobre Z / 2 ( fuente ).
Para ampliar la explicación de nosklo:
a = {}
b = ['some', 'list']
a[b] = 'some' # this won't work
a[tuple(b)] = 'some' # this will, same as a['some', 'list']
dict
implementación de Python .