2013-06-20 57 views
15

考慮:==運算符在Python字典上實際做了什麼?

>>> a = {'foo': {'bar': 3}} 
>>> b = {'foo': {'bar': 3}} 
>>> a == b 
True 

據蟒蛇DOC,you can indeed use字典上的==操作。

這裏實際發生了什麼? Python是否遞歸地檢查字典的每個元素以確保相等?它是否確保這些鍵完全匹配,並且這些值也完全匹配?

是否有文檔明確指出字典上的==是什麼意思?或者我是否必須實現自己的版本檢查平等?

(如果==運營商的工作,你爲什麼不哈希的類型的字典?也就是說,我爲什麼不能創建一組()類型的字典,或者使用字典作爲字典鍵?)

+0

字典不可散列,因爲它們是可變的,它們的數據對過去的狀態很敏感。很容易得到具有相等狀態的兩個字典,但由於字典的歷史(包含更多虛擬條目)而產生的不等散列 –

+1

@SlaterTyranus:您可以輕鬆地忽略虛擬條目;這不是問題。可變性是一個巨大的問題。 –

回答

12

Python是遞歸地檢查字典的每個元素以確保相等。請參閱C dict_equal() implementation,它檢查每個鍵和值(假設詞典的長度相同);如果字典b具有相同的密鑰,則PyObject_RichCompareBool測試值是否也匹配;這本質上是一個遞歸調用。

詞典不可散列,因爲它們的__hash__ attribute is set to None,最重要的是它們是可變,當用作字典鍵時,它是不允許的。

如果您要使用字典作爲密鑰,並通過現有的引用,然後更改密鑰,那麼該密鑰將不再插入到哈希表中的相同位置。使用另一個相同的字典(與未更改的字典或已更改的字典相同)試圖檢索該值現在將不再起作用,因爲將選取錯誤的時隙,或者密鑰不再相同。

2

如果字典對每個鍵具有相同的鍵和相同的值,則它們是相等的。

看一些例子:

dict(a=1,b=2)==dict(a=2,b=1) 
False 

dict(a=1,b=2)==dict(a=1,b=2,c=0) 
False 

dict(a=1,b=2)==dict(b=2,a=1) 
True 
12

docs

映射(字典)比較相等當且僅當它們的排序 (鍵,值)的列表比較相等。 [5]除了平等以外的結果是 一致解決,但沒有其他定義。 [6]

腳註[5]

實現高效計算此,無需構建 列表或排序。

腳註[6]

早期版本的Python的使用排序 (鍵,值)列表的字典比較,但是這是對的 一般情況下平等比較非常昂貴。甚至更早的Python版本僅通過身份比較 字典,但是這造成了驚喜,因爲 人們預計能夠通過將 與{}進行比較來測試字典中的空白。

+3

請注意,實際實現使用左側操作數的字典順序,並且如果鍵的數量不同,則先退出,然後只要其他字典中不存在鍵或相關值不會相等。 –

相關問題