为什么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
并且已经存在一个可以轻易使用的顺序敏感键比较,但它显然仅用作对odict丰富比较的后检查.
这是设计决定还是错误?如果这是一个设计决定,我在哪里可以找到理由的讨论?
看起来像OrderedDict
委托各种视图对象的dict
执行到常见的实现; 即使在Python 3.5中也是如此,它OrderedDict
获得了C加速实现(它将对象构造委托给_PyDictView_New
泛型视图的丰富比较函数并且不提供覆盖.
基本上,OrderedDict
视图以它们支持的相同顺序迭代OrderedDict
(因为没有成本),但是对于set
类似操作,它们的行为类似于set
使用内容相等,子集/超集检查等.
这使得忽略排序的选择在某种程度上有意义; 对于某些set
操作(例如&
,|
,^
),返回值是一个set
无秩序(因为没有OrderedSet
,即使有,你用的东西,像它的排序&
,其中排序可以在每个视图?是不同的),你"如果某些set
类似的操作对命令敏感而某些操作不敏感,则会出现不一致的行为.当两个OrderedDict
键视图对序列敏感时,它甚至会更奇怪,但是将OrderedDict
视图与dict
视图进行比较则不然.
正如我在评论中指出的那样,您可以keys
非常轻松地获得与订单敏感的比较:
from operator import eq # Verify that keys are the same length and same set of values first for speed # The `all` check then verifies that the known identical keys appear in the # same order. xy.keys() == yx.keys() and all(map(eq, xy, yx)) # If you expect equality to occur more often than not, you can save a little # work in the "are equal" case in exchange for costing a little time in the # "not even equal ignoring order case" by only checking length, not keys equality: len(xy) == len(yz) and all(map(eq, xy, yx))