使用其构造函数初始化OrderedDict的正确方法,使其保留初始数据的顺序?

问题:使用其构造函数初始化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实际维持订单?由于a dict具有不可预测的顺序,如果我的测试向量幸运地具有与dict不可预测的顺序相同的初始顺序,该怎么办?例如,如果不是d = OrderedDict({'b':2, 'a':1})我写d = OrderedDict({'a':1, 'b':2}),我可能会错误地得出结论认为该顺序已保留。在这种情况下,我发现a dict是按字母顺序排列的,但这可能并不总是正确的。什么是使用反例来验证数据结构是否保留顺序的可靠方法,而无需反复尝试测试向量,直到一个中断为止?

PS:我将在此留出参考:“ OrderedDict构造函数和update()方法都接受关键字参数,但是它们的顺序丢失了,因为Python的函数使用常规无序字典来调用语义传递关键字参数”

PPS:希望将来,OrderedDict也将保留kwarg的顺序(示例1):http : //bugs.python.org/issue16991

What’s the correct way to initialize an ordered dictionary (OD) so that it retains the order of initial data?

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])

Question:

  • Will an OrderedDict preserve the order of a list of tuples, or tuple of tuples or tuple of lists or list of lists etc. passed at the time of initialization (2nd & 3rd example above)?

  • How does one go about verifying if OrderedDict actually maintains an order? Since a dict has an unpredictable order, what if my test vectors luckily have the same initial order as the unpredictable order of a dict? For example, if instead of d = OrderedDict({'b':2, 'a':1}) I write d = OrderedDict({'a':1, 'b':2}), I can wrongly conclude that the order is preserved. In this case, I found out that a dict is ordered alphabetically, but that may not be always true. What’s a reliable way to use a counterexample to verify whether a data structure preserves order or not, short of trying test vectors repeatedly until one breaks?

P.S. I’ll just leave this here for reference: “The OrderedDict constructor and update() method both accept keyword arguments, but their order is lost because Python’s function call semantics pass-in keyword arguments using a regular unordered dictionary”

P.P.S : Hopefully, in future, OrderedDict will preserve the order of kwargs also (example 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对它的创建方式一无所知。

The OrderedDict will preserve any order that it has access to. The only way to pass ordered data to it to initialize is to pass a list (or, more generally, an iterable) of key-value pairs, as in your last two examples. As the documentation you linked to says, the OrderedDict does not have access to any order when you pass in keyword arguments or a dict argument, since any order there is removed before the OrderedDict constructor sees it.

Note that using a list comprehension in your last example doesn’t change anything. There’s no difference between OrderedDict([(i,i) for i in l]) and OrderedDict([('b', 'b'), ('a', 'a'), ('c', 'c'), ('aa', 'aa')]). The list comprehension is evaluated and creates the list and it is passed in; OrderedDict knows nothing about how it was created.


回答 1

# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b', 2), ('a', 1)])

是的,那行得通。根据定义,列表总是按照其表示方式进行排序。这也适用于列表理解,生成的列表的提供方式与提供数据的方式相同(即,来自列表的来源将是确定性的,来源于setdict不那么多)。

如何验证是否OrderedDict实际维持订单。由于字典具有不可预测的顺序,如果我的测试向量幸运地具有与字典的不可预测顺序相同的初始顺序,该怎么办?例如,如果不是d = OrderedDict({'b':2, 'a':1})我写d = OrderedDict({'a':1, 'b':2}),我可能会错误地得出结论认为该顺序已保留。在这种情况下,我发现a dict是按字母顺序排列的,但这可能并不总是正确的。也就是说,使用反例来验证数据结构是否保留顺序还是一种可靠的方法是一种可靠的方法,可以反复尝试测试向量,直到一个中断。

您保留2元组的源列表作为参考,并在进行单元测试时将其用作测试用例的测试数据。遍历它们并确保维持订单。

# An OD is represented by a list of tuples, so would this work?
d = OrderedDict([('b', 2), ('a', 1)])

Yes, that will work. By definition, a list is always ordered the way it is represented. This goes for list-comprehension too, the list generated is in the same way the data was provided (i.e. source from a list it will be deterministic, sourced from a set or dict not so much).

How does one go about verifying if OrderedDict actually maintains an order. Since a dict has an unpredictable order, what if my test vectors luckily has the same initial order as the unpredictable order of a dict?. For example, if instead of d = OrderedDict({'b':2, 'a':1}) I write d = OrderedDict({'a':1, 'b':2}), I can wrongly conclude that the order is preserved. In this case, I found out that a dict is order alphabetically, but that may not be always true. i.e. what’s a reliable way to use a counter example to verify if a data structure preserves order or not short of trying test vectors repeatedly until one breaks.

You keep your source list of 2-tuple around for reference, and use that as your test data for your test cases when you do unit tests. Iterate through them and ensure the order is maintained.