【发布时间】:2020-11-07 08:12:20
【问题描述】:
我有以下代码
import random
random.seed(42)
mylist = set(["A", "B", "C", "D", "E", "F", "G", "H"])
tn = random.sample(mylist, 4)
print(tn)
到目前为止,我预计这总是会打印相同的结果。但是,在每次连续运行时,它都会返回不同的 4 个字母序列。后来我发现它在删除 set 时是稳定的(在这个最小的例子中,除了触发问题之外没有其他目的)。
为什么有人会以不确定的方式实现set?我可以想象它的实现可能需要(伪)随机数,但即使那样我也希望我的程序仍然是确定性的,即使使用set。我还注意到这是版本相关的:
Python 版本:
- 2.7.12:稳定
- 3.5.2:不同的输出
- 3.6.12:不同的输出
如何使用set 并且仍然获得可重现的输出?在采样工作之前对mylist 和sorted 进行排序,但是您必须对在(天真地)空操作之后再次排序的列表进行排序是非常不直观的。
【问题讨论】:
-
未指定集合中元素的顺序,因此他们可能故意这样做是为了弄乱依赖特定顺序的应用程序。
-
但是
sorted()给了你另一个列表,所以你输了。 -
字符串 哈希 在运行之间不固定。
-
如果你需要重现性,你真的需要做更少的假设。如果您尝试在不同的计算机上进行测试,这在 2.7.12 上也不会稳定 - 在 32 位和 64 位版本上散列是不同的。
-
这已被 PEP 456 更改;哈希算法故意不可重现以关闭线性时间哈希表攻击。 python.org/dev/peps/pep-0456
标签: python random set random-seed