为什么 OrderedDict 键视图比较顺序不敏感?
Why does the OrderedDict keys view compare order-insensitive?
为什么 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 中的相同 "issue":
>>> xy.viewkeys() == yx.viewkeys()
True
它们是不同的类型,(odict_keys
是dict_keys
的子类)
>>> type(xy.keys())
odict_keys
>>> type({}.keys())
dict_keys
并且已经有一个 order-sensitive keys comparison available that they could have trivially used, but it's apparently only used as a post-check 用于 odict rich 比较。
这是设计决定还是错误?如果这是一个设计决定,我在哪里可以找到对理由的讨论?
看起来 OrderedDict
将各种视图对象的实现委托给公共 dict
实现;即使在 Python 3.5 中也是如此,其中 OrderedDict
获得了 C 加速实现(it delegates object construction to _PyDictView_New
and provides no override for the generic view's rich comparison function.
基本上,OrderedDict
视图以与支持 OrderedDict
相同的顺序进行迭代(因为这样做没有成本),但对于 set
类操作,它们执行例如 set
、使用内容相等、subset/superset 检查等
这使得忽略排序的选择在某种程度上是有意义的;对于某些 set
操作(例如 &
、|
、^
),return 值是没有顺序的 set
(因为没有OrderedSet
,即使有,对于类似 &
的内容,每个视图中的顺序可能不同?),如果某些 [=17],您会得到不一致的行为=]-like 操作是顺序敏感的,有些不是。如果两个 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))
我找不到任何已发布的内容,但我想这个逻辑可以证明这种行为是正确的:
如果你有两个字典,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
.
的兼容性
为什么 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 中的相同 "issue":
>>> xy.viewkeys() == yx.viewkeys()
True
它们是不同的类型,(odict_keys
是dict_keys
的子类)
>>> type(xy.keys())
odict_keys
>>> type({}.keys())
dict_keys
并且已经有一个 order-sensitive keys comparison available that they could have trivially used, but it's apparently only used as a post-check 用于 odict rich 比较。
这是设计决定还是错误?如果这是一个设计决定,我在哪里可以找到对理由的讨论?
看起来 OrderedDict
将各种视图对象的实现委托给公共 dict
实现;即使在 Python 3.5 中也是如此,其中 OrderedDict
获得了 C 加速实现(it delegates object construction to _PyDictView_New
and provides no override for the generic view's rich comparison function.
基本上,OrderedDict
视图以与支持 OrderedDict
相同的顺序进行迭代(因为这样做没有成本),但对于 set
类操作,它们执行例如 set
、使用内容相等、subset/superset 检查等
这使得忽略排序的选择在某种程度上是有意义的;对于某些 set
操作(例如 &
、|
、^
),return 值是没有顺序的 set
(因为没有OrderedSet
,即使有,对于类似 &
的内容,每个视图中的顺序可能不同?),如果某些 [=17],您会得到不一致的行为=]-like 操作是顺序敏感的,有些不是。如果两个 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))
我找不到任何已发布的内容,但我想这个逻辑可以证明这种行为是正确的:
如果你有两个字典,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
.