我正在尝试使用一个 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)])
如何确保它按照我想要的顺序创建?我正在尝试使用一个 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中,关键字参数的顺序不能得到保证。如果您想要这样做,您必须转移到实现了PEP 468的Python 3.6,保存函数中 **kwargs 的顺序.**kwargs
语法表示解释器应该收集所有不对应其他命名参数的关键字参数。但是,Python不会保留传递这些收集到的关键字参数的顺序。在某些情况下,顺序很重要。本PEP规定应该将收集到的关键字参数作为有序映射暴露在函数体中。dict
类型是否被排序除了CPython实现细节以外还存在一些不确定性,但是,是的,从3.6开始,关键字参数已经正式成为语言的一部分。 - TigerhawkT3很奇怪它还没有被提到,但是OrderedDict
的表示方式告诉你如何创建它以保持顺序:
OrderedDict([('a', 1), ('b', 2), ('c', 3)])
这种表示方式并非用作障碍物 - 原因是该表示方法可用于创建一个完全相同有序的OrderedDict
。
仅为了完整性(已经提到过),顺序会丢失,因为OrderedDict(a=1, b=2, c=3)
将这些参数捕获为**kwargs
,这是一个普通的无序字典。直到Python 3.6推出并做出承诺,即在像您一样传递它时,kwargs
的顺序将被保留:
Python 3.6 中的新功能
PEP 468:保留关键字参数排序
函数签名中的
**kwargs
现在保证是一个保持插入顺序的映射。
dict
现在维护插入顺序,但目前应该将此视为"实现细节,不应依赖此行为(这可能会在未来更改),但希望在修改语言规范以强制保留所有当前和未来Python实现的顺序语义之前,让这个新的字典实现在语言中运行几个版本。" - PM 2Ringdict
在3.6版本中有序是一项实现细节。:-) 不过在帖子下加上那条评论是很好的,它是一条重要的信息。谢谢。 - MSeifert保留关键字参数顺序
是一个实现细节。但是当然,让普通字典保持插入顺序确实使得保留关键字参数顺序变得更加容易。 :) - PM 2Ring阅读文档:
OrderedDict构造函数和update()方法都接受关键字参数,但它们的顺序会丢失,因为Python的函数调用语法使用常规无序字典来传递关键字参数。
您必须将输入作为元组序列(或现有的有序字典类型)传递以保留顺序。
请注意,Python 3.6现在提供了一个保证,即关键字参数按它们在代码中出现的顺序(从左到右)传递,感谢PEP 468,因此在Python 3.6及更高版本上,您的代码将正常工作。
(variable = value, )
会首先被合并成一个Python字典,而Python字典是无序的。正如您可以在 Init 签名中看到的那样,kwds
就是这个字典。Init signature: OrderedDict(self, *args, **kwds)
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)])
OrderedDict
呢? - wogslandsorted()
创建所需的映射:dict = {"a":"some_value", "b":"other_value", "c":"foo"}
ordered = OrderedDict(sorted(dict.items(), key=lambda t: t[0]))
OrderedDict
构造函数之前对其进行排序。
key=
部分设置了排序方式,t[0]
按字典键排序。