Python 为什么有序信息技术的价值不相等?
对于Python 3:Python 为什么有序信息技术的价值不相等?,python,python-3.x,dictionary,ordereddictionary,Python,Python 3.x,Dictionary,Ordereddictionary,对于Python 3: >>> from collections import OrderedDict >>> d1 = OrderedDict([('foo', 'bar')]) >>> d2 = OrderedDict([('foo', 'bar')]) 我想检查一下平等性: >>> d1 == d2 True >>> d1.keys() == d2.keys() True 但是: 你知道为什么值不
>>> from collections import OrderedDict
>>> d1 = OrderedDict([('foo', 'bar')])
>>> d2 = OrderedDict([('foo', 'bar')])
我想检查一下平等性:
>>> d1 == d2
True
>>> d1.keys() == d2.keys()
True
但是:
你知道为什么值不相等吗
我已经用Python 3.4和3.5对此进行了测试
在这个问题之后,我在Python Ideas邮件列表上发布了更多详细信息:
在python3中,
d1.values()
和d2.values()
是集合。abc.ValuesView
对象:
>>> d1.values()
ValuesView(OrderedDict([('foo', 'bar')]))
不要将它们作为对象进行比较,将它们转换为列表,然后进行比较:
>>> list(d1.values()) == list(d2.values())
True
调查其用于比较键的原因,在CPython的
\u collections\u abc.py
中,KeysView
继承自Set
,而ValuesView
不:
class KeysView(MappingView, Set):
class ValuesView(MappingView):
- 在
中跟踪值视图
及其父级:\uuuu eq\uuuu
MappingView==>size==>ABCMeta==>type==>object
仅在\uuuu eq\uuu
对象中实现,不被覆盖
- 另一方面,
直接从KeysView
继承Set
d1.values()
和d2.values()
是集合。abc.ValuesView
对象:
>>> d1.values()
ValuesView(OrderedDict([('foo', 'bar')]))
不要将它们作为对象进行比较,将它们转换为列表,然后进行比较:
>>> list(d1.values()) == list(d2.values())
True
调查其用于比较键的原因,在CPython的
\u collections\u abc.py
中,KeysView
继承自Set
,而ValuesView
不:
class KeysView(MappingView, Set):
class ValuesView(MappingView):
- 在
中跟踪值视图
及其父级:\uuuu eq\uuuu
MappingView==>size==>ABCMeta==>type==>object
仅在\uuuu eq\uuu
对象中实现,不被覆盖
- 另一方面,
直接从KeysView
继承Set
dict.keys()
和dict.values()
返回特殊的iterable类-分别是acollections.abc.KeysView
和acollections.abc.ValuesView
。第一个方法从集合
继承它的方法,第二个方法使用默认的对象 在Python3中,dict.keys()
和dict.values()
返回特殊的iterable类-分别是acollections.abc.KeysView
和acollections.abc.ValuesView
。第一个方法从集合
继承它的方法,第二个方法使用默认的对象 不幸的是,目前的两个答案都没有说明为什么要这样做,而是关注如何做到这一点。邮件列表的讨论非常精彩,所以我将总结一下:
对于odict.keys
/dict.keys
和odict.items
/dict.items
:
odict.keys
()支持比较,因为它符合collections.abc.Set
(它是一个类似集合的对象)。这是可能的,因为字典中的键
(有序与否)保证是唯一的和可散列的
odict.items
()也支持比较,原因与.keys
相同<允许code>itemsview执行此操作,因为如果item
s中的一个(特别是表示值的第二个元素)不可散列,则会引发相应的错误,但可以保证唯一性(因为键是唯一的):
即使键对应的值不相同,实际上也应该相等吗?大概也许不是?这两种方式都不是直截了当的,会导致不可避免的混乱
但需要指出的一点是,将它们与键
和项
进行比较并不容易,总之,@abarnett的另一个评论是:
如果您认为我们可以定义多集应该做什么,尽管它们没有标准的多集类型或ABC,并将其应用于值视图,那么下一个问题是,对于不可散列的值,如何在比二次时间更好的时间内做到这一点。(你也不能假设在这里排序。)让值视图挂起30秒,然后返回你直觉上想要的答案,而不是在20毫秒内给出错误的答案,这会是一种改进吗?(无论哪种方式,您都将学到同样的教训:不要比较值和视图。我宁愿在20毫秒内学习。)
不幸的是,目前的两个答案都没有说明这是为什么,而是关注如何做到这一点。邮件列表的讨论非常精彩,所以我将总结一下:
对于odict.keys
/dict.keys
和odict.items
/dict.items
:
odict.keys
()支持比较,因为它符合collections.abc.Set
(它是一个类似集合的对象)。这是可能的,因为字典中的键
(有序与否)保证是唯一的和可散列的
odict.items
()也支持比较,原因与.keys
相同<允许code>itemsview执行此操作,因为如果item
s中的一个(特别是表示值的第二个元素)不可散列,则会引发相应的错误,但可以保证唯一性(因为键是唯一的):
即使键对应的值不相同,实际上也应该相等吗?大概也许不是?这两种方式都不是直截了当的,会导致不可避免的混乱
但需要指出的一点是,将它们与键
和项
进行比较并不容易,总之,@abarnett的另一个评论是:
如果您认为我们可以定义多集应该做什么,尽管没有标准的多集类型