矩阵作为字典键 [英] Matrix as dictionary key

查看:239
本文介绍了矩阵作为字典键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始使用 numpy 及其矩阵模块(非常有用!),我想使用矩阵对象作为字典的关键字,所以我检查了矩阵是否实现了 __哈希__ 方法: / p>

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

很好,所以这意味着它可以成为字典的关键:

 >>> m1 = matrix('1 2 3; 4 5 6; 7 8 9')
>>>> m1
矩阵([[1,2,3],
[4,5,6],
[7,8,9]])
>> ; m2 =矩阵('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'}

现在,我们继续测试:

 >>> matrix_dict [m1] 
'first'
>>>> matrix_dict [matrix('1 2 3; 4 5 6; 7 8 9')]
追溯(最近的最后一次调用):
文件< stdin>,第1行,< module> ;
KeyError:matrix([[1,2,3],
[4,5,6],
[7,8,9]])

什么?所以,它适用于相同的矩阵,但它不适用于具有完全相同内容的另一个矩阵?让我们看看什么 __哈希__ 返回:

 >>>哈希(m1)
2777620
>>>> same_as_m = matrix('1 2 3; 4 5 6; 7 8 9')
>>>> hash(same_as_m)
-9223372036851998151
>>>哈希(矩阵('1 2 3; 4 5 6; 7 8 9'))#与m一样
2777665

$ b $因此, __ hash __ 方法从 numpy 为相同的矩阵返回不同的值



这是对的吗?那么这是否意味着它不能用作字典键?如果不能使用,为什么要实现 __ hash __

解决方案>

使用可变对象作为字典的关键字是错误的,因为它的哈希值应在更改数据后立即更改,但插入时使用的值将被保留。



在我的测试中,numpy在Python 3.2.2中引发了一个TypeError:

  TypeError:unhashable type: 'matrix'

但是在Python 2.7中,它仍然允许散列,但是当更改数据时哈希值不会改变,所以它是相当无用的字典密钥,因为许多矩阵对象被添加到具有相同哈希的字典将降级散列表,所以插入将是 O(n ^ 2)而不是 O(1)



也许他们没有删除哈希值,以避免在Python 2.x上打破一些API,但不要依赖它!


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?

解决方案

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!

这篇关于矩阵作为字典键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆