矩阵作为字典键
问题描述:
如果
matrix
有
__hash__
方法来实现
我刚刚使用numpy
及其matrix
模块(非常非常有用!)开始,我想用一个矩阵对象作为字典的关键,所以我检查:矩阵作为字典键
>>> from numpy import matrix
>>> hasattr(matrix, '__hash__')
True
它确实!很好,所以这意味着它可以成为字典的关键:
>>> 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'}
工作!现在,让我们继续测试:
>>> 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]])
什么?所以,它适用于相同的矩阵,但它不适用于具有完全相同内容的另一个矩阵?让我们来看看__hash__
回报:
>>> 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
所以,从matrix
回报numpy
不同值的相同matrix
的__hash__
方法。
这是正确的吗?那么,这是否意味着它不能用作字典键?如果不能使用,为什么要执行__hash__
?
答
使用可变对象作为字典的关键字是错误的,因为只要您更改数据,它的哈希值就会改变,但插入时使用的值将会保留。
在我的测试中,在numpy的Python的3.2.2引发TypeError:
TypeError: unhashable type: 'matrix'
但在Python 2.7版它仍然允许散列但是,当你更改数据的哈希值永远不会改变,所以它是相当无用字典键,因为许多matrix
对象被添加到具有相同散列的字典中会降低散列表,因此插入将是O(n^2)
而不是O(1)
。
也许他们没有删除哈希值以避免在Python 2.x上打破某些API,但不要依赖它!
默认情况下Python对象是可散列的 - 您必须为不可用的类禁用它。可能仅仅是'numpy'的一部分。 – millimoose 2012-01-11 02:06:51
矩阵是一个ndarray,默认情况下它们也是可散列的 - 我假设你也有同样的问题。 – jozzas 2012-01-11 02:41:41
@jozzas,我很惊讶有可能使用矩阵作为字典键,因为我知道ndarrays不能用作键,矩阵是ndarray的子类 – 2012-01-11 02:54:59