Matrix as a dictionary

I just started using numpy and its matrix module (very very useful!), And I wanted to use a matrix object as a dictionary key, so I checked if matrix t23> had:

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

And so it is! Nice, so this means that it can be a dictionary key:

 >>> 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'} 

Works! Now let's continue 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 exactly the 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__ matrix from numpy method returns different values ​​for the same matrix .

Is it correct? Does this mean that it cannot be used as a dictionary key? And if it cannot be used, why did it implement __hash__ ?

+6
source share
1 answer

It would be wrong to use a mutable object as a dictionary key, because its hash should change as soon as you change the data, but the value used during insertion will be saved.

In my tests, numpy in Python 3.2.2 raises a TypeError:

 TypeError: unhashable type: 'matrix' 

But on Python 2.7, it still allows hashing, but the hash value never changes when the data changes, so it is pretty useless as a dictionary key, because many matrix objects added to the dictionary with the same hash worsen the hash table, therefore inserting O(n^2) instead of O(1) .

They may not have removed the hash value so as not to violate some Python 2.x APIs, but do not rely on it!

+9
source

Source: https://habr.com/ru/post/905676/


All Articles