2013-06-20 26 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

请注意,实际实现使用左侧操作数的字典顺序,并且如果键的数量不同,则先退出,然后只要其他字典中不存在键或相关值不会相等。 –

相关问题