问题描述
Python dict
的视图对象的比较与我预期的不同:
a = {0 : 'a',1 : 'b'}
b = {1 : 'b',0 : 'a'}
print(a == b) # True
print(a.keys() == b.keys()) # True
print(a.values() == b.values()) # False
print(a.items() == b.items()) # True
对于dict.values()
是False
有什么特殊原因吗?
其实在同一个dict
的情况下(甚至不是副本),也是False
:
a = {0 : 'a',1 : 'b'}
print(a.values() == a.values()) # False
这个视图对象的相等性意味着什么?
解决方法
字典视图类实现它们自己的相等方法。 dict.values()
的文档特别指出:
一个 dict.values()
视图和另一个视图之间的相等比较将始终返回 False。这也适用于将 dict.values()
与其自身进行比较
对于 dict.keys()
和 dict.items()
,dictionary views 的文档说:
键视图是类似设置的,因为它们的条目是唯一且可散列的。如果所有值都是可散列的,因此 (key,value)
对是唯一且可散列的,则项目视图也是类似集合的。 (值视图不被视为类集合,因为条目通常不是唯一的。)对于类集合视图,为抽象基类 collections.abc.Set
定义的所有操作都可用(例如,{{1} }、==
或 <
)。
keys
和 items
视图是类似集合的(或者对于具有不可散列值的 items
视图大多类似集合)——它们在许多情况下的行为类似于 set
对象方式,特别是,对此类视图执行 in
测试很容易。这让这些视图支持基于两个视图是否包含相同元素的高效 ==
操作。
对于 values
视图,没有实现此类 ==
操作的好方法,因此 values
视图不要为 {{1 }}。它们只是从 ==
继承默认的 __eq__
实现,因此两个 object
视图只有在它们是同一个对象时才会被认为是相等的。即使对于同一个 dict 的两个视图,如果它们实际上是同一个视图对象,您也只会得到 values
:
True
,
dict
是无序的,这意味着只要 a
中的所有键都存在于 b
中并且 b
中的所有键都存在于 a
和这些键的所有值都相等,两个集合相等。
如果您尝试检查 a
和 b
是否是相同的实例,那么您可以使用 is
。
>>> a = {0 : 'a',1 : 'b'}
>>> b = {1 : 'b',0 : 'a'}
>>> a is b
False
>>> a = {0 : 'a',1 : 'b'}
>>> b = a
>>> a is b
True
至于a.values() == b.values()
为什么返回False
的问题,这是Python语言做出的选择。引用自 Python 文档:
一个 dict.values() 视图和另一个视图之间的相等比较将 总是返回 False。这也适用于将 dict.values() 与 本身:
>>> d = {'a': 1}
>>> d.values() == d.values()
False