Python OrderedDict Isn';你没点吗?
我正在尝试使用一个Python OrderedDict Isn';你没点吗?,python,python-2.7,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)]) 如何确保它是按照我想要的正确顺序创建的?这是因为您传递的关键字参数(variable=value,)将首
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)])
如何确保它是按照我想要的正确顺序创建的?这是因为您传递的关键字参数
(variable=value,)
将首先合并到Python字典中。Python字典是无序的kwds
将是您可以在Init签名中看到的字典
Init signature: OrderedDict(self, *args, **kwds)
这就是传递关键字参数时,OrderedDict将如何在内部初始化:
for key, value in kwds.items():
self[key] = value
由于kwds
是无序的,因此您将获得无序的OrderedICT
您可以这样创建有序的dict:
from collections import OrderedDict
from string import ascii_lowercase
d = OrderedDict()
for a,b in enumerate(ascii_lowercase[:3], 1):
d[b] = a
或:
输出:
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
阅读:
OrderedDict构造函数和update()方法都接受关键字参数,但它们的顺序会丢失,因为Python的函数调用语义使用常规无序字典传入关键字参数
必须以元组序列(或现有的有序dict类型)的形式传递输入以保持顺序
请注意,由于Python 3.6和更高版本,现在的Python 3.6可以正常工作。
集合。OrderedDict
跟踪元素添加到其中的顺序。这将在循环中正常工作:
c = collections.OrderedDict()
for a,b in zip('abc', (1,2,3)):
c[a] = b
但是,表达式orderedict(a=1,b=2,c=3)
通过向其构造函数传递几个关键字参数来创建一个orderedict
。在Python2.7中,关键字参数的顺序不能保证。如果您想这样做,就必须转到Python 3.6,它实现了PEP 468
函数定义中的**kwargs
语法表示解释器应收集与其他命名参数不对应的所有关键字参数。但是,Python并没有保留收集的关键字参数传递给函数的顺序。在某些情况下,顺序很重要。此PEP规定收集的关键字参数在函数体中作为有序映射公开
您可以使用
sorted()
创建所需的映射:
这会在将项目传递给OrderedDict
构造函数之前对其进行排序
key=
部分设置排序,并且t[0]
按字典键排序。奇怪的是,它还没有被提及,但是OrderedDict
的表示方式向您展示了如何创建它,以便保持顺序:
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
表示法是这样并不是一个障碍,因为表示法可以用来创建相同的有序的OrderedDict
为了完整性(已经提到过),顺序丢失是因为
OrderedDict(a=1,b=2,c=3)
将这些参数捕捉为**kwargs
,这是一个正常的无序命令。至少在Python3.6出现并发布之前,kwargs
的顺序将在您传递它时保持不变,就像您所做的那样:
Python 3.6的新增功能
PEP 468:保留关键字参数顺序
函数签名中的**kwargs
现在保证为保留插入顺序的映射
好的,但是如何创建所需的
OrderedDict
?@wogsland应该使用ascii\u小写?:)呵呵。没有意识到他们实际上决定记录这种行为并保证它。很高兴知道。@ShadowRanger-关于基本dict
类型的排序除了CPython实现细节外,其他都是一样的,但是,是的,关键字参数从3.6开始是语言的正式组成部分。@Copperfield-是的,它向构造函数发送一个参数,然后以类似于演示的循环的方式迭代该参数。这个参数永远不会发送到任意顺序的容器,它是一个序列,因此它的顺序是有保证的。可能值得一提的是,Python 3.6中的普通dict
现在保持插入顺序,但目前应该“将其视为一个实现细节,不应该依赖它”(这在将来可能会发生变化,但在将语言规范更改为所有当前和未来Python实现的命令保留语义之前,希望在一些版本中使用这种新的dict实现。”@pm2实际上,3.6中保留关键字参数顺序的不是一个实现细节。3.6中所有其他dict
都是一个实现细节。:-)但是在帖子下面有这样的评论是很好的,这是重要的信息。谢谢。@同意!在我之前的评论中,我并没有暗示保留关键字参数顺序是一个实现细节。但当然,使用普通dict维护插入顺序肯定会使保留关键字参数顺序更容易。:)key=isunderenced-简单地按元组(key,value)排序将产生一个键排序字典
dict = {"a":"some_value", "b":"other_value", "c":"foo"}
ordered = OrderedDict(sorted(dict.items(), key=lambda t: t[0]))
OrderedDict([('a', 1), ('b', 2), ('c', 3)])