我该如何测试字典总是以相同的顺序?

时间:2018-05-22 20:28:33

标签: python dictionary testing ordereddict

这是一个测试问题,而不是实施问题。

我有一个生成JSON的程序,我希望能够一致地比较输出,所以我将所有的dicts转换为OrderedDicts。

我已经搜索过了,而且我非常有信心我得到了所有这些,但是良好的编程仍然需要测试。我不确定如何实际测试我的字典是按照相同的顺序出现的,因为我告诉他们,相比之下,他们刚刚以相同的顺序出现......

有没有办法强制Python随机化其非订购的dicts?

ETA:我使用的是python 2.7。我还有18个月的时间来转换这件事......它已经在名单上了......

1 个答案:

答案 0 :(得分:2)

我不确定你真的需要测试这个,但如果你这样做......

在CPython 2.7中,测试它真的没有意义。元素将按任意顺序排列 - 这意味着它们可以任意顺序以与插入顺序相同的顺序结束,并且没有办法强迫它们不存在。

在CPython 3.3-3.5中,情况更糟。元素不仅按任意顺序排列,而且每次运行测试时都以不同的任意顺序排列。这意味着您的测试看起来可能正常,因为它恰好有3!-1 / 3!的工作机会,然后您将检查一个不稳定且无用的测试。

然而,在CPython 3.6-3.7中,顺序实际上与OrderedDict类似,但不完全相同,这意味着可以可靠地测试的东西。如果从dict中删除然后插入,则旧插槽将被重用。当然,OrderedDict不是这样。所以:

>>> d1, d2 = {}, collections.OrderedDict()
>>> for i in range(10):
...     d1[i] = d2[i] = i
>>> del d1[2]
>>> del d2[2]
>>> d1[2] = d2[2] = 1000
>>> d1
{0: 0, 1: 1, 2: 1000, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9
>>> d2
OrderedDict([(0, 0),
         (1, 1),
         (3, 3),
         (4, 4),
         (5, 5),
         (6, 6),
         (7, 7),
         (8, 8),
         (9, 9),
         (2, 1000)])

然而,这依赖于CPython 3.6-3.7的实现细节,这几乎是你试图测试你没有做的事情。在那次考试中这样做是否可以接受?