我试图使用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)])
如何确保以我想要的正确顺序创建它?
答案 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]
按字典键排序。