简体   繁体   English

将字典传递给OrderedDict有什么问题?

[英]What's wrong with passing a dict to OrderedDict?

I'm reading @Martijn Pieters' response to Converting dict to OrderedDict . 我正在阅读@Martijn Pieters对将dict转换为OrderedDict的回应。 The main point of his answer is that passing a regular dict to OrderedDict() will not retain the order as desired, because the dict that you are passing has already "lost" any semblance of order. 他的回答的主要观点是将常规字典传递给OrderedDict()将不会保留所需的顺序,因为您传递的字典已经“丢失”了任何相似的顺序。 His solution is to pass tuples that make up the dict's key/value pairs instead. 他的解决方案是传递组成dict的键/值对的元组。

However, I also noticed the following in the docs : 但是,我在文档中也注意到以下内容:

Changed in version 3.6: With the acceptance of PEP 468, order is retained for keyword arguments passed to the OrderedDict 版本3.6中已更改:接受PEP 468后,将保留传递给OrderedDict的关键字参数的顺序

Does this invalidate the issue that Martijn points out (can you now pass a dict to OrderedDict), or am I misinterpreting? 这是否会使Martijn指出的问题无效(你现在可以将一个字典传递给OrderedDict),还是我误解了?

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)])

I get this same (correct) order if I run a for key in ... loop over the OrderedDict as well, seeming to imply it's OK to pass the dict itself. 如果我在OrderedDict上运行for key in ...循环,那么我得到同样的(正确的)顺序,似乎暗示可以传递dict本身。

Edit : this was also contributing a bit to my confusion: Are dictionaries ordered in Python 3.6+? 编辑 :这也引起了我的困惑: 是否在Python 3.6+中订购了字典?

Order is retained for keyword arguments passed to the OrderedDict 传递给OrderedDict的关键字参数保留顺序

What this means is that the following is guaranteed to preserve the order: 这意味着以下内容可以保证保留顺序:

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

that is, the order in which the keyword arguments are passed is retained in **kwargs . 也就是说,传递关键字参数的顺序保留在**kwargs This, in Python 3.6, is a language feature ; 这在Python 3.6中是一种语言特性 ; all other implementations need to follow suit. 所有其他实现都需要效仿。

How this works is, in order for this call to be performed, a dictionary is created that holds the keyword arguments. 这是如何工作的,为了执行此调用,创建了一个包含关键字参数的字典。 Being a dict , prior to 3.6 , it lost information about the order in which these were supplied. 作为一个dict ,在3.6之前,它丢失了关于这些词的提供顺序的信息。

With PEP 468 getting accepted in 3.6, this is guaranteed to now use an ordered mapping that holds on to this information (in CPython, the "ordered mapping" happens to be a dict but, that's an implementation detail -- Update: A language feature as of Python 3.7.). 随着PEP 468在3.6中被接受,现在保证使用有序映射来保存此信息(在CPython中,“有序映射”恰好是一个dict但是,这是一个实现细节 - 更新:语言功能从Python 3.7开始。)


Using OrderedDict(ship) , as you currently do, also preserves the order in 3.6 because dict has that implementation now, not due to PEP 468. This is something you shouldn't depend on as it is considered an implementation detail of the CPython implementation; 正如您目前所做的那样,使用OrderedDict(ship)也会保留3.6的顺序,因为dict现在具有该实现,而不是由于PEP 468.这是您不应该依赖的,因为它被认为是CPython实现的实现细节; in the future this might change (and it looks like it will) but, until then, you shouldn't depend on it. 在未来,这可能会改变(看起来会如此),但在此之前,你不应该依赖它。

As of Python 3.7 , the previous is now guaranteed to preserve the order across implementations as dict insertion order is now a language feature. 从Python 3.7开始 ,之前的版本现在可以保证在实现中保持顺序,因为dict插入顺序现在是一种语言功能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM