问题:使用其构造函数初始化OrderedDict的正确方法,使其保留初始数据的顺序?
初始化有序词典(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
实际维持订单?由于adict
具有不可预测的顺序,如果我的测试向量幸运地具有与dict不可预测的顺序相同的初始顺序,该怎么办?例如,如果不是d = OrderedDict({'b':2, 'a':1})
我写d = OrderedDict({'a':1, 'b':2})
,我可能会错误地得出结论认为该顺序已保留。在这种情况下,我发现adict
是按字母顺序排列的,但这可能并不总是正确的。什么是使用反例来验证数据结构是否保留顺序的可靠方法,而无需反复尝试测试向量,直到一个中断为止?
PS:我将在此留出参考:“ OrderedDict构造函数和update()方法都接受关键字参数,但是它们的顺序丢失了,因为Python的函数使用常规无序字典来调用语义传递关键字参数”
PPS:希望将来,OrderedDict也将保留kwarg的顺序(示例1):http : //bugs.python.org/issue16991
回答 0
OrderedDict将保留其有权访问的任何订单。将有序数据传递给它进行初始化的唯一方法是传递键值对的列表(或更普遍地讲,是可迭代的),如最后两个示例中所示。正如您链接的文档所述,当您传入关键字参数或dict参数时,OrderedDict无法访问任何顺序,因为其中的任何顺序都在OrderedDict构造函数看到之前被删除。
请注意,在上一个示例中使用列表推导并没有什么改变。OrderedDict([(i,i) for i in l])
和之间没有区别OrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c'), ('aa', 'aa')])
。评估列表理解并创建列表,并将其传入;OrderedDict对它的创建方式一无所知。
回答 1
# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b', 2), ('a', 1)])
是的,那行得通。根据定义,列表总是按照其表示方式进行排序。这也适用于列表理解,生成的列表的提供方式与提供数据的方式相同(即,来自列表的来源将是确定性的,来源于set
或dict
不那么多)。
如何验证是否
OrderedDict
实际维持订单。由于字典具有不可预测的顺序,如果我的测试向量幸运地具有与字典的不可预测顺序相同的初始顺序,该怎么办?例如,如果不是d = OrderedDict({'b':2, 'a':1})
我写d = OrderedDict({'a':1, 'b':2})
,我可能会错误地得出结论认为该顺序已保留。在这种情况下,我发现adict
是按字母顺序排列的,但这可能并不总是正确的。也就是说,使用反例来验证数据结构是否保留顺序还是一种可靠的方法是一种可靠的方法,可以反复尝试测试向量,直到一个中断。
您保留2元组的源列表作为参考,并在进行单元测试时将其用作测试用例的测试数据。遍历它们并确保维持订单。