2012-01-11 101 views
6
如果 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__

+4

默認情況下Python對象是可散列的 - 您必須爲不可用的類禁用它。可能僅僅是'numpy'的一部分。 – millimoose 2012-01-11 02:06:51

+0

矩陣是一個ndarray,默認情況下它們也是可散列的 - 我假設你也有同樣的問題。 – jozzas 2012-01-11 02:41:41

+0

@jozzas,我很驚訝有可能使用矩陣作爲字典鍵,因爲我知道ndarrays不能用作鍵,矩陣是ndarray的子​​類 – 2012-01-11 02:54:59

回答

9

使用可變對象作爲字典的關鍵字是錯誤的,因爲只要您更改數據,它的哈希值就會改變,但插入時使用的值將會保留。

在我的測試中,在numpy的Python的3.2.2引發TypeError:

TypeError: unhashable type: 'matrix' 

但在Python 2.7版它仍然允許散列但是,當你更改數據的哈希值永遠不會改變,所以它是相當無用字典鍵,因爲許多matrix對象被添加到具有相同散列的字典中會降低散列表,因此插入將是O(n^2)而不是O(1)

也許他們沒有刪除哈希值以避免在Python 2.x上打破某些API,但不要依賴它!