Por Favor Ayuda
Alexis Roda
alexis.roda.villalonga en gmail.com
Mar Jun 27 18:29:22 CEST 2006
En/na Chema Cortes ha escrit:
> 2006/6/23, Alexis Roda <alexis.roda.villalonga en gmail.com>:
>> La clave debe ser "hashable", los diccionarios no lo son. Si no recuerdo
>> mal los objetos mutables (listas, diccionarios ...) no pueden actuar
>> como claves de un diccionario. Los objetos inmutables ("string", tuplas
>> ...) si pueden. Por supuesto nada te impide derivar una clase
>> MiDiccionario(dict) que si sea hashsable.
>
> Para que quede claro como podría ser:
>
> class MiDiccionario(dict):
> def __hash__(self):
> return tuple(self.items()).__hash__()
>
> d=MiDiccionario( {'clave1':"Esta es la clave 1", 2:"otra clave"} )
> print d
> --> {2: 'otra clave', 'clave1': 'Esta es la clave 1'}
>
> r={d:d}
> print r
> --> {{2: 'otra clave', 'clave1': 'Esta es la clave 1'}: {2: 'otra
> clave', 'clave1': 'Esta es la clave 1'}}
Ya que estamos vamos a completar los detalles :-).
Hacer un diccionario "hashable" tiene su miga. Si el valor devuelto por
__hash__() depende del contenido del diccionario (claves y/o valores) su
valor cambiará al cambiar el diccionario. Eso nos obliga a tratar las
instancias de MiDiccionario como de solo lectura una vez utilizadas como
claves:
>>> d.__hash__()
-616709607
>>> d['otra clave'] = 12345
>>> d.__hash__()
-2015796712
>>> print r[d]
KeyError: {'otra clave': 12345, 2: 'otra clave', 'clave1': 'Esta es la
clave 1'}
Si se implementa __hash__() de una forma que no tenga en cuenta el
"contenido" del diccionario, por ejemplo:
class MiDiccionario(dict):
def __hash__(self):
return id(self)
podemos encontrarnos con otro tipo de anomalías:
>>> d1 = MiDiccionario({'a': 1})
>>> d2 = MiDiccionario({'a': 1})
>>> d1 == d2
True
>>> d1 is d2
False
>>> d = {}
>>> d[d1] = 1
>>> d[d2]
KeyError: {'a': 1}
>>> d1.__hash__()
-1210493204
>>> d2.__hash__()
-1210493060
Mi conclusión seria que antes de utilizar un diccionario como clave de
otro diccionario habría que pensarlo cinco minutos. La idea de utilizar
un objeto (potencialmente) cambiante como identificador de otro objeto
resulta un tanto ... extraña.
Saludos
Más información sobre la lista de distribución Python-es