I've just started using numpy
and its matrix
module (very very useful!), and I wanted to use a matrix object as the key of a dictionary, so I checked if matrix
had the __hash__
method implemented:
>>> from numpy import matrix
>>> hasattr(matrix, '__hash__')
True
And it does! Nice, so it means that it can be the key of a dictionary:
>>> 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'}
Worked! Now, let's keep testing:
>>> 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]])
What? So, it works for the same matrix, but it doesn't work for another matrix with the exact same content? Let's see what __hash__
returns:
>>> 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
So, the __hash__
method of the matrix
from numpy
returns different values for the same matrix
.
Is this right? So, does it means that it cannot be used as a dictionary key? And if it can't be used, why does it have __hash__
implemented?
00:19 A key must be immutable—that is, unable to be changed. These are things like integers, floats, strings, Booleans, functions. Even tuples can be a key. A dictionary or a list cannot be a key.
A tuple containing a list cannot be used as a key in a dictionary. Answer: True. A list is mutable. Therefore, a tuple containing a list cannot be used as a key in a dictionary.
Accessing Values The data elements in a matrix can be accessed by using the indexes. The access method is same as the way data is accessed in Two dimensional array.
It would be wrong to use a mutable object as a key of a dictionary because its hash should change as soon as you change the data, but the value used on insertion will be kept.
On my tests, numpy at Python 3.2.2 raise a TypeError:
TypeError: unhashable type: 'matrix'
But on Python 2.7 it still allows hashing but the hash value never changes when you change data, so it is pretty useless as dictionary key because many matrix
objects being added to the dictionary having the same hash will degrade the hash table so insertion will be O(n^2)
instead of O(1)
.
Maybe they didn't remove the hash value to avoid breaking some API on Python 2.x, but do not rely on it!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With