Curiosidad sobre __hash__()

Francesc Alted faltet en pytables.org
Jue Feb 5 16:34:26 CET 2009


A Thursday 05 February 2009, David García escrigué:
> > A ver, si a y b *son* el mismo objeto ((2,), que no necesariamente
> > es la misma dirección de memoria), la hash ha de ser la misma, no?
>
> No se trata del mismo objeto, además de diferentes direcciones de
> memoria en caso de ser mutables (una lista) si "a" cambia, "b" no lo
> hace (Como curiosidad las listas no tienen hash, solo sus elementos,
> si no son listas, y en caso de que la tupla solo contenga listas
> __hash__ falla)

Tienes razón, tal vez me he expresado mal ya que objeto tiene un 
significado muy preciso en Python.  Me refería al hecho que a y b 
representan a la misma, digamos, 'entidad' en Python.  Quiero decir, 
que (2,) y (2,) representan a la misma abstracción en Python, aunque 
sean instancias diferentes.

>
> Tienen el mismo hash porque las tuplas para calcularlo usan el hash
> de sus miembros, y en este caso son el mismo id(a[0]) == id(b[0]).
>
> Imagino que al ser 2 un elemento con valor constante Python usa su
> dirección tantas veces como 2 sea referenciado.

Pues me parece que no.  Como se ve en:

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

la manera de calcular el hash de un entero no es retornar su dirección 
de memoria como sugieres, sino simplemente su valor.  Esto a menos que 
sea -1, en cuyo caso el hash es -2:

In [24]: hash(-1)
Out[24]: -2

In [25]: hash(-2)
Out[25]: -2

lo cual representa un caso de colisión entre el -1 y el -2 (el único 
para enteros ordinarios, los enteros largos son otro caso bastante 
diferente).

Saludos,

-- 
Francesc Alted
_______________________________________________
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