关于python:将dict传递给OrderedDict有什么问题?

What's wrong with passing a dict to OrderedDict?

我正在阅读@Martijn Pieters对将dict转换为OrderedDict的回应。 他回答的主要观点是将常规字典传递给OrderedDict()将不会保留所需的顺序,因为你传递的字典已经"丢失"了任何相似的顺序。 他的解决方案是传递组成dict的键/值对的元组。

但是,我在文档中也注意到以下内容:

Changed in version 3.6: With the acceptance of PEP 468, order is
retained for keyword arguments passed to the OrderedDict

这是否会使Martijn指出的问题无效(你现在可以将一个字典传递给OrderedDict),还是我误解了?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from collections import OrderedDict

ship = {'NAME': 'Albatross',
         'HP':50,
         'BLASTERS':13,
         'THRUSTERS':18,
         'PRICE':250}
print(ship) # order lost as expected
{'BLASTERS': 13, 'HP': 50, 'NAME': 'Albatross', 'PRICE': 250, 'THRUSTERS': 18}
print(OrderedDict(ship)) # order preserved even though a dict is passed?
OrderedDict([('NAME', 'Albatross'),
             ('HP', 50),
             ('BLASTERS', 13),
             ('THRUSTERS', 18),
             ('PRICE', 250)])

如果我在OrderedDict上运行for key in ...循环,我得到同样(正确)的顺序,似乎暗示可以通过dict本身。

编辑:这也引起了我的困惑:是否在Python 3.6+中订购了字典?


Order is retained for keyword arguments passed to the OrderedDict

这意味着以下内容可以保证保留顺序:

1
od = OrderedDict(a=20, b=30, c=40, d=50)

也就是说,传递关键字参数的顺序保留在**kwargs中。这在Python 3.6中是一种语言特性;所有其他实现都需要效仿。

这是如何工作的,为了执行此调用,创建了一个包含关键字参数的字典。作为dict,在3.6之前,它丢失了关于这些提供顺序的信息。

随着PEP 468在3.6中被接受,这保证现在使用有序映射来保存此信息(在CPython中,"有序映射"恰好是dict但是,这是一个实现细节 - 更新:A Python 3.7中的语言特性。

正如您目前所做的那样,使用OrderedDict(ship)也会保留3.6中的顺序,因为dict现在具有该实现,而不是由于PEP 468.这是您不应该依赖的内容,因为它被视为实现细节。 CPython实现;在未来,这可能会改变(看起来会如此),但在此之前,你不应该依赖它。

从Python 3.7开始,现在可以保证前一个版本保持整个实现的顺序,因为dict插入顺序现在是一种语言功能。