初始化有序字典(OD)以使其保持初始数据顺序的正确方法是什么?
from collections import OrderedDict
# Obviously wrong because regular dict loses order
d = OrderedDict({'b':2, 'a':1})
# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b',2), ('a', 1)])
# What about using a list comprehension, will 'd' preserve the order of 'l'
l = ['b', 'a', 'c', 'aa']
d = OrderedDict([(i,i) for i in l])
问题:
OrderedDict
是否会保留初始化时传递的元组列表、元组或列表元组或列表列表等的顺序(上面的第二个和第三个示例)?OrderedDict
是否确实保持了顺序?由于dict
具有不可预测的顺序,如果我的测试向量幸运地具有与dict的不可预测顺序相同的初始顺序,该怎么办?例如,如果我写的不是d = OrderedDict({'b':2, 'a':1})
,而是d = OrderedDict({'a':1, 'b':2})
,我可能会错误地得出顺序被保留的结论。在本例中,我发现dict
是按字母顺序排序的,但这并不总是正确的。使用反例验证数据结构是否保持顺序的可靠方法是什么,除非反复尝试测试向量,直到其中一个被打破?附言:“OrderedDict构造函数和reference()方法都接受关键字参数,但它们的顺序丢失了,因为OrderedDict的函数使用常规的无序字典调用语义传递关键字参数。”
附注:希望在未来,OrderedDict也能保持kwargs的顺序(示例1):http://bugs.python.org/issue16991
发布于 2014-08-25 14:35:06
OrderedDict将保留它有权访问的任何顺序。将有序数据传递给它以进行初始化的惟一方法是传递一个键值对列表(或者,更一般地说,是一个可迭代的),如您的最后两个示例所示。正如您所链接的文档所述,当您传入关键字参数或dict参数时,OrderedDict不能访问任何顺序,因为在OrderedDict构造函数看到它之前,任何顺序都会被删除。
请注意,在上一个示例中使用列表理解不会改变任何事情。OrderedDict([(i,i) for i in l])
和OrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c'), ('aa', 'aa')])
之间没有区别。计算列表理解并创建列表,然后传入列表;OrderedDict对列表是如何创建的一无所知。
发布于 2021-01-19 04:10:34
使用生成器表达式也是可能的(而且效率更高):
d = OrderedDict((i, i) for i in l)
显然,在l
的这种微不足道的情况下,好处可以忽略不计,但如果l
对应于迭代器或从生成器产生结果,例如用于解析和迭代大型文件,则差异可能非常大(例如,避免将整个内容加载到内存中)。例如:
def mygen(filepath):
with open(filepath, 'r') as f:
for line in f:
yield [int(field) for field line.split()]
d = OrderedDict((i, sum(numbers)) for i, numbers in enumerate(mygen(filepath)))
https://stackoverflow.com/questions/25480089
复制相似问题