繁体   English   中英

OrderedDict没有订购?

[英]OrderedDict Isn't Ordered?

我正在尝试使用OrderedDict ,但它仍然不按顺序创建。 例如,

from collections import OrderedDict
OrderedDict(a=1,b=2,c=3)

产量

OrderedDict([('a', 1), ('c', 3), ('b', 2)])

而不是预期的

OrderedDict([('a', 1), ('b', 2), ('c', 3)])

我怎样才能确保按照我想要的正确顺序创建它?

collections.OrderedDict跟踪元素添加到它的顺序。 这在循环中可以正常工作:

c = collections.OrderedDict()
for a,b in zip('abc', (1,2,3)):
    c[a] = b

但是,表达式OrderedDict(a=1,b=2,c=3)通过将几个关键字参数传递给其构造函数来创建OrderedDict 在Python 2.7中,不保证关键字参数的顺序。 如果你想要,你将不得不转向Python 3.6,它实现了PEP 468, 保留了函数中** kwargs的顺序

函数定义中的**kwargs语法指示解释器应收集与其他命名参数不对应的所有关键字参数。 但是,Python不保留将这些收集的关键字参数传递给函数的顺序。 在某些情况下,订单很重要。 此PEP规定收集的关键字参数作为有序映射在函数体中公开。

奇怪的是它尚未被提及,但OrderedDict表示向您展示了如何创建它以便保持顺序:

OrderedDict([('a', 1), ('b', 2), ('c', 3)])

它并不意味着表示就像是一个障碍 - 这是因为该表示可以用来创建一个相同的有序OrderedDict


为了完整性(已经提到过),由于OrderedDict(a=1, b=2, c=3)这些参数捕获为**kwargs ,这是一个正常的无序dict ,因此订单会丢失。 至少直到python 3.6出现并承诺 ,当你传递它时,将保留kwargs的顺序:

Python 3.6中的新功能

PEP 468:保留关键字参数顺序

**kwargs函数签名中的**kwargs现在保证是一个插入顺序保留映射。

阅读文档

OrderedDict构造函数和update()方法都接受关键字参数,但它们的顺序丢失,因为Python的函数使用常规无序字典调用语义传入关键字参数。

必须将输入作为一系列元组(或现有的有序dict类型)传递以保持排序。

请注意,Python 3.6现在可以保证关键字参数按照它们在代码中出现的顺序(从左到右)传递,这要归功于PEP 468 ,因此在Python 3.6及更高版本中,您的代码才能正常工作。

这是因为您传递的关键字参数(variable = value, )将首先合并到Python字典中。 Python字典是无序的。 你可以在Init签名中看到kwds那个字典。

Init signature: OrderedDict(self, *args, **kwds)

这是在传递关键字参数时内部初始化OrderedDict的方式

for key, value in kwds.items():
   self[key] = value

由于kwds是无序的,你将得到一个无序的OrderedDict。

您可以像这样创建有序的dict:

from collections import OrderedDict
from string import ascii_lowercase

d = OrderedDict()
for a,b in enumerate(ascii_lowercase[:3], 1):
    d[b] = a

要么:

n=3
d = OrderedDict(zip(ascii_lowercase[:n], range(1,n+1))) 
print d 

输出:

OrderedDict([('a', 1), ('b', 2), ('c', 3)])

您可以使用sorted()创建所需的映射:

dict = {"a":"some_value", "b":"other_value", "c":"foo"}
ordered = OrderedDict(sorted(dict.items(), key=lambda t: t[0]))

这会在将项目传递给OrderedDict构造函数之前对其进行排序。

key=部分设置排序, t[0]按字典键排序。

暂无
暂无

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

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