我这样做是为了测试randint的随机性:
>>> from random import randint
>>>
>>> uniques = []
>>> for i in range(4500): # You can see I was optimistic.
... x = randint(500, 5000)
... if x in uniques:
... raise Exception('We duped %d at iteration number %d' % (x, i))
... uniques.append(x)
...
Traceback (most recent call last):
File "<stdin>", line 4, in <module>
Exception: We duped 887 at iteration number 7
我尝试了大约10倍以上,我得到的最好结果是在转发器之前迭代了121次。这是您从标准库中获得的最佳结果吗?
答案 0 :(得分:275)
答案 1 :(得分:44)
在归咎于Python之前,你应该提高一些概率&amp;统计理论。首先阅读birthday paradox
顺便说一句,Python中的random
模块使用Mersenne twister PRNG,它被认为是非常好的,具有巨大的周期并且经过了广泛的测试。所以请放心,你很好。
答案 2 :(得分:40)
如果您不想要重复序列,请生成顺序数组并使用random.shuffle
答案 3 :(得分:38)
答案 4 :(得分:15)
真正的随机性肯定包括在整个可能值集耗尽之前重复值。否则它不会是随机的,因为您可以预测值不会重复多长时间。
如果你掷过骰子,你肯定经常排成3个六分......
答案 5 :(得分:5)
Python的随机实现实际上是最先进的:
答案 6 :(得分:4)
您正在4500
范围内生成500 <= x <= 5000
个随机数。然后检查每个数字是否已生成。 birthday problem告诉我们,如果n
次尝试超出范围d
,则其中两个数字匹配的概率是多少。
您还可以反转公式以计算在生成重复的可能性超过50%
之前必须生成的数量。在这种情况下,>50%
次迭代后您有79
次机会找到重复的数字。
答案 7 :(得分:4)
那不是转发器。转发器是指重复相同的序列。不只是一个数字。
答案 8 :(得分:1)
您已经定义了4501个值(500-5000)的随机空间,并且您正在迭代4500次。你基本上保证在你写的测试中发生碰撞。
以另一种方式思考:
因此,到达45/4500时,该插入有1%的可能性是重复,并且随着每个后续插入,该概率会不断增加。
要创建真正测试随机函数能力的测试,请增加可能随机值的范围(例如:500-500000)您可能会,也可能不会获得欺骗。但是你平均会得到更多的迭代。
答案 9 :(得分:0)
对于有此问题的其他人,我使用了uuid.uuid4(),它就像一个魅力。
答案 10 :(得分:0)
有生日悖论。考虑到这一点,你意识到你所说的是找到“764,3875,4290,4378,764”或类似的东西并不是随机的,因为该序列中的数字会重复。真正的方法是将序列相互比较。我写了一个python脚本来做这件事。
from random import randint
y = 21533456
uniques = []
for i in range(y):
x1 = str(randint(500, 5000))
x2 = str(randint(500, 5000))
x3 = str(randint(500, 5000))
x4 = str(randint(500, 5000))
x = (x1 + ", " + x2 + ", " + x3 + ", " + x4)
if x in uniques:
raise Exception('We duped the sequence %d at iteration number %d' % (x, i))
else:
raise Exception('Couldn\'t find a repeating sequence in %d iterations' % (y))
uniques.append(x)