47

考虑:

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

根据python doc,您确实可以在字典上使用运算==符。

这里实际发生了什么?Python 是否递归检查字典的每个元素以确保相等?是否确保键相同匹配,并且值也相同匹配?

是否有文档准确指定==字典上的含义?或者我是否必须实施自己的平等检查版本?

(如果==运算符有效,为什么字典不能散列?也就是说,为什么我不能创建字典的 set() 或使用字典作为字典键?)

4

3 回答 3

29

Python 递归地检查字典的每个元素以确保相等。请参阅C dict_equal()实现,它检查每个键和值(前提是字典的长度相同);如果字典b具有相同的键,则 aPyObject_RichCompareBool测试值是否也匹配;这本质上是一个递归调用。

字典不是可散列的,因为它们的__hash__属性设置为None,并且最重要的是它们是mutable,这在用作字典键时是不允许的。

如果您要使用字典作为键,并通过现有引用更改键,则该键将不再插入哈希表中的相同位置。使用另一个相等的字典(无论是未更改的字典还是已更改的字典)来尝试检索该值现在将不再起作用,因为将选择错误的插槽,或者键将不再相等。

于 2013-06-20T15:07:04.773 回答
18

来自文档

映射(字典)比较相等当且仅当它们的排序(键,值)列表比较相等。[5]平等以外的结果得到一致解决,但没有另外定义。[6]

脚注[5]

该实现有效地计算了这一点,而无需构建列表或排序。

脚注[6]

早期版本的 Python 使用排序(键,值)列表的字典比较,但这对于比较相等的常见情况来说非常昂贵。更早版本的 Python 仅按身份比较字典,但这引起了意外,因为人们希望能够通过将字典与 {} 进行比较来测试字典是否为空。

于 2013-06-20T15:10:32.380 回答
10

如果字典具有相同的键和每个对应键的相同值,则它们是相等的。

看一些例子:

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
于 2013-06-20T15:09:36.490 回答