![](/img/trans.png)
[英]RuntimeError: OrderedDict mutated during iteration (Python3)
[英]Python OrderedDict iteration
为什么我的python OrderedDict被初始化为'乱序'?
这里的解决方案不如解释那么有趣。 这里有些东西,我只是没有得到,也许扩张会帮助别人和我。
>>> from collections import OrderedDict
>>> spam = OrderedDict(s = (1, 2), p = (3, 4), a = (5, 6), m = (7, 8))
>>> spam
OrderedDict([('a', (5, 6)), ('p', (3, 4)), ('s', (1, 2)), ('m', (7, 8))])
>>> for key in spam.keys():
... print key
...
# this is 'ordered' but not the order I wanted....
a
p
s
m
# I was expecting (and wanting):
s
p
a
m
来自文档 :
OrderedDict构造函数和
update()
方法都接受关键字参数,但它们的顺序丢失,因为Python的函数使用常规无序字典调用语义传入关键字参数。
所以初始化会丢失排序,因为它基本上是用**kwargs
调用构造函数。
编辑:就解决方案而言 (不仅仅是解释 ) - 如OP的评论所指出的那样,传入单个元组列表将起作用:
>>> from collections import OrderedDict
>>> spam = OrderedDict([('s',(1,2)),('p',(3,4)),('a',(5,6)),('m',(7,8))])
>>> for key in spam:
... print(key)
...
s
p
a
m
>>> for key in spam.keys():
... print(key)
...
s
p
a
m
这是因为它只获得一个参数,一个列表。
@Chris Krycho很好地解释了为什么失败了。
如果你查看OrderedDict的repr(),你会得到一个如何从头开始传递顺序的提示:你需要使用(键,值)对的列表来保持列表给出的键的顺序。
这是我之前做的一个:
>>> from collections import OrderedDict
>>> spamher = OrderedDict(s=6, p=5, a=4, m=3, h=2, e=1, r=0)
>>> spamher
OrderedDict([('h', 2), ('m', 3), ('r', 0), ('s', 6), ('p', 5), ('a', 4), ('e', 1)])
>>>
>>> list(spamher.keys())
['h', 'm', 'r', 's', 'p', 'a', 'e']
>>>
>>> spamher = OrderedDict([('s', 6), ('p', 5), ('a', 4), ('m', 3), ('h', 2), ('e', 1), ('r', 0)])
>>> list(spamher.keys())
['s', 'p', 'a', 'm', 'h', 'e', 'r']
>>>
(正巧是在Python 3.3.0你原来的例子spam
保存在从一开始就它们原来的顺序按键。我改spamher
得到arounf这一点)。
正如其他 答案所提到的,尝试将dict传递给OrderedDict或使用关键字参数不会保留顺序。 传递元组有点难看,这就是Python。 它应该是美丽的。
您可以使用
AB
__getitem__
上一类以具有类似字典的语法创建OrderedDict“文字”:
from collections import OrderedDict
class OD(object):
"""This class provides a nice way to create OrderedDict "literals"."""
def __getitem__(self, slices):
if not isinstance(slices, tuple):
slices = slices,
return OrderedDict((slice.start, slice.stop) for slice in slices)
# Create a single instance; we don't ever need to refer to the class.
OD = OD()
现在您可以使用类似dict的语法来创建OrderedDict:
spam = OD['s': (1, 2),
'p': (3, 4),
'a': (5, 6),
'm': (7, 8)]
assert(''.join(spam.keys()) == 'spam')
这是有效的,因为在方括号内,Python创建切片文字,如果你稍微眯一下,它恰好看起来像dict语法。
OD
类可以从错误检查中受益,但这表明它是如何工作的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.