【问题标题】:What does the == operator actually do on a Python dictionary?== 运算符实际上在 Python 字典上做了什么?
【发布时间】:2013-06-20 15:05:53
【问题描述】:

考虑:

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

根据 python 文档,you can indeed use 是字典上的 == 运算符。

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

是否有文档准确说明字典中的== 的含义?或者我是否必须实现我自己的平等检查版本?

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

【问题讨论】:

  • dicts 不可散列,因为它们是可变的并且它们的数据对过去的状态很敏感。由于字典的历史(包含更多虚拟条目),很容易拥有两个状态相同但哈希不相等的字典
  • @SlaterTyranus:您可以轻松忽略虚拟条目;这不是问题。可变性是一个大问题。

标签: python dictionary


【解决方案1】:

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

字典不可散列,因为它们的__hash__ attribute is set to None,而且最重要的是它们是可变的,当用作字典键时这是不允许的。

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

【讨论】:

    【解决方案2】:

    来自docs

    映射(字典)比较相等当且仅当它们已排序 (key, value) 列表比较相等 .[5] 不相等的结果是 一致地解决,但没有另外定义。 [6]

    脚注[5]:

    实现有效地计算了这个,无需构造 列表或排序。

    脚注[6]:

    早期版本的 Python 使用排序的字典比较 (key, value) 列表,但这对于常见的情况来说是非常昂贵的 比较平等。一个更早版本的 Python 比较 仅按身份的字典,但这引起了意外,因为 人们期望能够通过以下方式测试字典的空虚 将其与 {} 进行比较。

    【讨论】:

    • 请注意,实际实现对左侧操作数使用字典顺序,如果键的数量不同,则首先退出,然后只要键不存在于另一个字典或关联的值不比较相等。
    【解决方案3】:

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

    看一些例子:

    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
    

    【讨论】:

      猜你喜欢
      • 2018-11-29
      • 2017-04-28
      • 1970-01-01
      • 2013-06-02
      • 2020-11-21
      • 2015-02-26
      • 2017-06-29
      • 2013-06-13
      • 2021-10-25
      相关资源
      最近更新 更多