Curiosidad sobre __hash__()

Francesc Alted faltet en pytables.org
Jue Feb 5 12:30:44 CET 2009


A Thursday 05 February 2009, Jesus Cea escrigué:
> Rodrigo Gallardo wrote:
> >>> Me ha sorprendido que la función hash "solo"
> >>> devuelva un entero.
> >>>
> >>> (1,2,3,4).__hash__()
> >>> 89902565
> >>>
> >>> ¿No os parece que aumenta mucho las probabilidades
> >>> de que se produzca una colisión no deseada en un
> >>> diccionario por ej.?
> >>
> >> Bueno, si la función hash está bien elegida, un entero de 32-bit
> >> da para 2**31 hash diferentes, y ya tendria que ser grande el
> >> diccionario para que esto sea un problema.
> >
> > Esto es la "paradoja del cumpleaños"
>
> La implementación "normal" de "hash" (en Python) es la posición de
> memoria del objeto. Así, dos objetos solo coinciden en "__hash__()"
> si su posición de memoria es la misma. Osea, se trata del mismo
> objeto.
>
> En un mundo 32 bits, con 2^32 valores para "__hash__()" es
> suficiente, porque no puedes direccionar más memoria que esa.
>
> En resumen, la implementación por defecto de "__hash__()" no es un
> verdadero hash, y no está sujeto a la paradoja del cumpleaños.

Uh, creo que no:

In [6]: a = (2,)

In [7]: id(a)
Out[7]: 136302508

In [8]: hash(a)
Out[8]: -1658481943

o sea, que el hash no devuelve la posición de memoria y se trata de un 
verdadero hash.  Aquí hay un ejemplo de como se calculan los hashes 
para algunos objetos:

http://effbot.org/zone/python-hash.htm

Para los curiosos, la manera en que se localizan la claves del 
diccionario se explica aquí:

http://wiki.python.org/moin/DictionaryKeys

Saludos,

-- 
Francesc Alted
------------ próxima parte ------------
_______________________________________________
Lista de correo Python-es 
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes


Más información sobre la lista de distribución Python-es