为什么OrderedDict键视图比较顺序不敏感?

时间:2015-12-16 19:35:34

标签: python python-3.x python-internals ordereddictionary

为什么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_keysdict_keys的子类)

>>> type(xy.keys())
odict_keys
>>> type({}.keys())
dict_keys

并且已经有一个order-sensitive keys comparison available他们可以轻易使用,但它显然只用作post-check来进行丰富的比较。

这是设计决定还是错误?如果它是一个设计决定,我在哪里可以找到关于理由的讨论?

2 个答案:

答案 0 :(得分:6)

看起来OrderedDict将各种视图对象的实现委托给公共dict实现;即使在Python 3.5中,OrderedDict获得了C加速实现(it delegates object construction to _PyDictView_Newprovides 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()

对于任何类型的字典,此函数的行为应该相同(OrderedDictdict的类型)。如果这样的函数开始返回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的兼容性。