OrderedDict没有订购?

时间:2017-01-26 04:31:11

标签: python python-2.7

我试图使用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)])

如何确保以我想要的正确顺序创建它?

5 个答案:

答案 0 :(得分:48)

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,Preserving the order of **kwargs in a function

  

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

答案 1 :(得分:18)

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

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

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

为了完整性(已经提到过),订单会丢失,因为OrderedDict(a=1, b=2, c=3)将这些参数捕获为**kwargs,这是正常的无序 - dict。至少在python 3.6出现之前,promise使kwargs的顺序在您传递时保留**kwargs的顺序:

  

Python 3.6中的新功能

     

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

     现在,函数签名中的

[OR]保证是一个插入顺序保留映射。

答案 2 :(得分:12)

阅读the docs

  

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

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

请注意,Python 3.6现在provides a guarantee that keyword arguments are passed in the same order they appear in the code (from left to right),感谢PEP 468,因此在Python 3.6及更高版本中,您的代码才能正常工作。

答案 3 :(得分:3)

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

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

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

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

由于kwds无序,您将获得无序的OrderedDict。

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

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

答案 4 :(得分:0)

您可以使用sorted()

创建所需的映射
dict = {"a":"some_value", "b":"other_value", "c":"foo"}
ordered = OrderedDict(sorted(dict.items(), key=lambda t: t[0]))

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

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

相关问题