集合的迭代顺序在每次运行中不同

41 投票
7 回答
22371 浏览
提问于 2025-04-16 04:54

为什么在Python中,集合的遍历顺序会在不同的运行中变化?我该如何让它在每次运行时保持一致呢?

我知道Python集合的遍历顺序是随机的。比如我把'a'、'b'和'c'放进一个集合里,然后遍历它们,出来的顺序可能会是任何顺序。

我观察到,在同一次程序运行中,顺序是保持不变的。也就是说,如果我的程序连续两次遍历同一个集合,得到的顺序是一样的。但是,如果我连续两次运行这个程序,顺序就会在不同的运行中变化。

不幸的是,这导致我的一个自动化测试失败了,因为它只是比较两次运行程序的输出。我并不在乎实际的顺序,但我希望它在每次运行时都能保持一致。

我想到的最佳解决方案是:

  1. 把集合复制到一个列表中。
  2. 对这个列表进行任意排序。
  3. 遍历这个列表,而不是集合。

有没有更简单的解决办法呢?

注意:我在StackOverflow上找到了类似的问题,但没有一个是专门针对如何让每次运行结果一致的。

7 个回答

17

可以使用对称差异(^)运算符来比较你两个集合,看看它们之间有没有不同的地方:

In [1]: s1 = set([5,7,8,2,1,9,0])
In [2]: s2 = set([9,0,5,1,8,2,7])
In [3]: s1
Out[3]: set([0, 1, 2, 5, 7, 8, 9])
In [4]: s2
Out[4]: set([0, 1, 2, 5, 7, 8, 9])
In [5]: s1 ^ s2
Out[5]: set()
35

之所以每次运行时集合的遍历顺序会变化,是因为Python默认使用了哈希种子随机化。简单来说,就是每次运行时,程序在处理集合时的顺序不是固定的,而是随机的。

如果你想让这个随机种子保持不变,可以通过设置一个环境变量来实现,这个变量叫做 PYTHONHASHSEED。这样做的结果是,虽然集合的遍历顺序依然是随机的,但每次运行时的顺序是一样的,这样就能保证结果的一致性。

哈希种子随机化其实是一种安全措施,目的是为了让攻击者更难通过输入特定的数据来导致程序出现异常行为,比如产生很多哈希冲突。在进行单元测试时,这个问题并不重要,所以在测试时改变哈希种子是合理的做法。

14

你想要的事情是不可能的。任意的意思就是任意的。

我的解决办法和你的一样,如果你想把这个集合和另一个集合进行比较,就必须先对它进行排序。

撰写回答