为什么OrderedDict
键视图比较顺序不敏感?
>>> from collections import OrderedDict
>>> xy = OrderedDict([('x', None), ('y', None)])
>>> yx = OrderedDict([('y', None), ('x', None)])
>>> xy == yx
False
>>> xy.keys() == yx.keys()
True
OrderedDict键视图应该表现得像OrderedSet,但它的行为与dict.keys
相同(即像通常的set
一样)。
相同"问题"在python2中:
>>> xy.viewkeys() == yx.viewkeys()
True
它们是不同的类型,(odict_keys
是dict_keys
的子类)
>>> type(xy.keys())
odict_keys
>>> type({}.keys())
dict_keys
并且已经有一个order-sensitive keys comparison available他们可以轻易使用,但它显然只用作post-check来进行丰富的比较。
这是设计决定还是错误?如果它是一个设计决定,我在哪里可以找到关于理由的讨论?
答案 0 :(得分:6)
看起来OrderedDict
将各种视图对象的实现委托给公共dict
实现;即使在Python 3.5中,OrderedDict
获得了C加速实现(it delegates object construction to _PyDictView_New
和provides no override的通用视图rich comparison function,这种情况仍然如此。
基本上,OrderedDict
次观看次序使用他们支持OrderedDict
的相同顺序进行迭代(因为这样做没有成本),但对于set
- 类似的操作,它们就像{ {1}},使用内容相等,子集/超集检查等。
这使得忽略排序的选择在某种程度上有意义;对于某些set
操作(例如set
,&
,|
),返回值为^
,没有订单(因为没有set
},即使有,你在哪个排序用于OrderedSet
,在每个视图中排序可能不同?),如果某些&
- 你会得到不一致的行为操作是对订单敏感的,有些则不是。如果两个set
键视图对订单敏感,那么它甚至会更奇怪,但将OrderedDict
个视图与OrderedDict
个视图进行比较则不然。
正如我在评论中所指出的,您可以通过以下方式轻松获得与订单相关的dict
比较:
keys
答案 1 :(得分:0)
我找不到任何已发布的内容,但我猜这种逻辑可以证明这种行为是正确的:
如果您有两个词典,d1和d2,您希望比较键检查它们是否具有相同的键,对吧?
def compare_dict_keys(d1, d2):
d1.keys() == d2.keys()
对于任何类型的字典,此函数的行为应该相同(OrderedDict
是dict
的类型)。如果这样的函数开始返回False
只是因为d1和d2已经排序,那似乎是错误的。
换句话说,这些都应该评估相同(他们这样做):
>>> {1:2, 3:4}.keys() == {3:4, 1:2}.keys()
True
>>> {1:2, 3:4}.keys() == OrderedDict([(3,4),(1,2)]).keys()
True
>>> OrderedDict([(1,2),(3,4)]).keys() == OrderedDict([(3,4),(1,2)]).keys()
True
但是OrderedDict
是特定的,不是吗?
OrderedDict
为您提供的是在您进行迭代时保证订单。 OrderedDict.keys()
存在相同的保证,但不会破坏与dict
的兼容性。