Python OrderedDict不能保持元素顺序

50

我试图创建一个OrderedDict对象,但刚刚创建它,元素就全混乱了。

我所做的是:

from collections import OrderedDict
od = OrderedDict({(0,0):[2],(0,1):[1,9],(0,2):[1,5,9]})

元素不按我指定的顺序呈现

od
OrderedDict([((0, 1), [1, 9]), ((0, 0), [2]), ((0, 2), [1, 5, 9])])

docs.python.org没有提供示例,我无法弄清楚为什么顺序会变得混乱。非常感谢任何帮助。

1个回答

92

你的问题在于你正在构建一个 dict 来提供初始数据给 OrderedDict - 这个 dict 不会 保存任何顺序,所以在传递给 OrderedDict 之前顺序就已经丢失了。

解决方案是从有序数据类型中构建 - 最简单的方式是使用一个 tuplelist

>>> from collections import OrderedDict
>>> od = OrderedDict([((0, 0), [2]), ((0, 1), [1, 9]), ((0, 2), [1, 5, 9])])
>>> od
OrderedDict([((0, 0), [2]), ((0, 1), [1, 9]), ((0, 2), [1, 5, 9])])

值得注意的是,这就是为什么 OrderedDict 在其字符串表示中使用它的语法的原因 - 字符串表示应尽可能尝试成为有效的Python代码以复制对象,这就是为什么输出使用元组列表而不是字典。

编辑:从Python 3.6开始,kwargs 有序 ,因此您可以使用关键字参数,前提是您使用最新版本的Python。

自3.7版起,对于dict也是如此(在CPython 3.6中是这样,但语言规范没有指定,因此仍然需要使用OrderedDict以保持兼容性)。这意味着如果您可以假设一个3.7+的环境,通常可以完全放弃OrderedDict,或者从普通的dict构建一个特定的功能(例如:顺序对于相等很重要)的OrderedDict


12
值得注意的是,仅向构造函数传递名称/值并不足以设置顺序。 >>> from collections import OrderedDict >>> OrderedDict(one=1, two=2, three=3, four=4) OrderedDict([('four', 4), ('one', 1), ('three', 3), ('two', 2)]) - Eric Smith
1
@EricSmith确实,同样的原因 - Python中的可变关键字参数(**kwargs)被存储为字典 - 因此当发生这种情况时,顺序就会丢失。请注意,PEP-468提供了一个简单的解决方案 - 对于kwargs,使用OrderedDict而不是特性,尽管现在还没有实现,但也许将来会有。 - Gareth Latty
2
@GarethLatty 现在在 python 3.6 中,他们实现了 PEP-468。 - Copperfield

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接