使用Python random.shuffle随机播放的列表的最大长度?

时间:2010-06-17 14:48:23

标签: python random shuffle

我有一个列表,我用随机播放的shuffle函数(random.shuffle)进行随机播放

然而,Python参考声明:

  

注意,即使相当小的len(x),x的排列总数也大于大多数随机数生成器的周期;这意味着永远不会产生长序列的大多数排列。

现在,我想知道这个“相当小的len(x)”是什么意思。 100,1000,10000,......

3 个答案:

答案 0 :(得分:61)

TL; DR:它在超过2080个元素的列表上“中断”,但不要太担心:)

完整答案:

首先,请注意“清单”列表可以(概念上)理解为生成列表元素的所有可能排列,并随机选择其中一个排列。

然后,您必须记住所有自包含的计算机化随机数生成器实际上是“伪”随机的。也就是说,它们实际上并不是随机的,而是依赖于一系列因素来尝试生成一个难以在高级或有目的地再现中猜到的数字。这些因素通常是先前生成的数字。所以,实际上,如果你连续使用一个随机发生器一定次数,你最终会重新开始获得相同的序列(这是文档所指的“句号”)。

最后,Lib / random.py上的文档字符串(随机模块)说“[随机数生成器]的周期是2**19937-1。”

所以,考虑到所有这些,如果你的列表有2**19937个或更多的排列,那么其中一些将永远不会通过改组列表获得。您(再次,在概念上)生成列表的所有排列,然后生成随机数x,并选择第x个排列。下一次,您生成另一个随机数y,并选择第y个排列。等等。但是,由于排列的次数多于你得到的随机数(因为,最多在2**19937-1生成的数字后,你会再次开始获得相同的排列),你将再次开始选择相同的排列。 / p>

所以,你知道,这并不是你的名单有多长(尽管这确实进入了等式)。此外,2**19937-1是一个很长的数字。但是,仍然,根据你的洗牌需求,你应该记住所有这些。在一个简单的情况下(并通过快速计算),对于没有重复元素的列表,2081个元素将产生2081!个排列,这超过2**19937

答案 1 :(得分:19)

我最初在Python源代码中写了这个评论,所以也许我可以澄清一下; - )

当评论被引入时,Python的Wichmann-Hill生成器的周期要短得多,我们甚至无法生成一副卡片的所有排列。

这个时期现在天文数字大,2080对于当前上限是正确的。可以加强文档以更多地说明这一点 - 但它们会变得非常繁琐。

有一个非常简单的解释:周期P的PRNG具有P个可能的起始状态。起始状态完全决定了产生的排列。因此,周期P的PRNG不能产生超过P个不同的排列(并且这是绝对上限 - 它可能无法实现)。这就是比较N的原因!在这里,P是正确的计算。确实如此:

>>> math.factorial(2080) > 2**19937 - 1
False
>>> math.factorial(2081) > 2**19937 - 1
True

答案 2 :(得分:4)

他们的意思是n个物体的排列(注意n!)非常快地变得荒谬地高。

基本上是n! = n x n-1 x ... x 1;例如,5! = 5 x 4 x 3 x 2 x 1 = 120这意味着有120种可能的方式来改组5项列表。

在相同的Python页面文档中,他们将2 ^ 19937-1作为句点,即4.something×10 ^ 6001或其他东西。基于维基百科关于阶乘的页面,我猜2000!应该是那个。 (对不起,我没找到确切的数字。)

所以基本上有很多可能的排列方式,这可能是由于没有真正的理由担心它不会发生的事情。

但是,如果这确实是一个问题(讨厌的客户要求保证随机性?),您也可以将任务卸载给某些第三方;例如,请参阅http://www.random.org/