2012-01-11 33 views
6

acabo de empezar a usar numpy y su módulo matrix (muy muy útil!), Y quería utilizar un objeto de matriz como la clave de un diccionario, lo que he comprobado si matrix había puesto en práctica el método __hash__ :Matrix como el diccionario de clave

>>> from numpy import matrix 
>>> hasattr(matrix, '__hash__') 
True 

Y lo hace! Niza, lo que significa que puede ser la clave de un diccionario:

>>> m1 = matrix('1 2 3; 4 5 6; 7 8 9') 
>>> m1 
matrix([[1, 2, 3], 
     [4, 5, 6], 
     [7, 8, 9]]) 
>>> m2 = matrix('1 0 0; 0 1 0; 0 0 1') 
>>> m2 
matrix([[1, 0, 0], 
     [0, 1, 0], 
     [0, 0, 1]]) 
>>> matrix_dict = {m1: 'first', m2: 'second'} 

funcionó! Ahora, sigamos probando:

>>> matrix_dict[m1] 
'first' 
>>> matrix_dict[matrix('1 2 3; 4 5 6; 7 8 9')] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
KeyError: matrix([[1, 2, 3], 
        [4, 5, 6], 
        [7, 8, 9]]) 

¿Qué? Entonces, ¿funciona para la misma matriz, pero no funciona para otra matriz con el mismo contenido exacto? Vamos a ver qué __hash__ rendimientos:

>>> hash(m1) 
2777620 
>>> same_as_m = matrix('1 2 3; 4 5 6; 7 8 9') 
>>> hash(same_as_m) 
-9223372036851998151 
>>> hash(matrix('1 2 3; 4 5 6; 7 8 9')) # same as m too 
2777665 

Por lo tanto, el método de los __hash__matrix de numpy devuelve valores diferentes para el mismo matrix.

¿Es esto correcto? Entonces, ¿significa que no se puede usar como una clave de diccionario? Y si no se puede usar, ¿por qué tiene implementado __hash__?

+4

Los objetos de Python son manejables de forma predeterminada; debe deshabilitarlo para las clases que no se pueden cambiar. Podría ser solo una omisión por parte de 'numpy'. – millimoose

+0

Una matriz es una ndarray debajo, y también son lavables por defecto, supongo que también tendrías el mismo problema al usarlas. – jozzas

+0

@jozzas, me sorprendió que fuera posible utilizar una matriz como clave de diccionario porque sé que las ndarrays no pueden usarse como claves y la matriz es una subclase de ndarray –

Respuesta

9

Sería incorrecto utilizar un objeto mutable como clave de un diccionario porque su hash debería cambiar tan pronto como cambie los datos, pero se mantendrá el valor utilizado en la inserción.

En mis pruebas, numpy en Python 3.2.2 elevar un TypeError:

TypeError: unhashable type: 'matrix' 

Pero en Python 2.7 todavía permite hash pero el valor hash nunca cambia cuando cambia los datos, por lo que es bastante inútil como clave del diccionario porque muchos objetos matrix que se agregan al diccionario con el mismo hash degradarán la tabla hash, por lo que la inserción será O(n^2) en lugar de O(1).

Tal vez no eliminaron el valor hash para evitar romper alguna API en Python 2.x, ¡pero no confíe en ello!

Cuestiones relacionadas