random.shuffle(lst_shuffle, random.random)
Run Code Online (Sandbox Code Playgroud)
我知道后一部分是一个可选参数.但它究竟做了什么呢.我不明白这是什么意思.这是来自文档.
random.random()返回[0.0,1.0]范围内的下一个随机浮点数.
我也看到了这个,这是0,0,1,0这个范围的意思吗?
Pseudorandom number generators
Most, if not all programming languages have libraries that include a pseudo-random
number generator. This generator usually returns a random number between 0 and 1 (not
including 1). In a perfect generator all numbers have the same probability of being selected but
in the pseudo generators some numbers have zero probability.
Run Code Online (Sandbox Code Playgroud)
现有的答案可以很好地解决问题的具体问题,但我认为值得一提的是一个侧面问题:为什么你特别想要传递一个替代的"随机生成器"而shuffle不是random模块中的其他函数.引用文档:
注意,对于相当小的len(x),x的排列总数大于大多数随机数生成器的周期; 这意味着永远不会产生长序列的大多数排列.
这里的短语"随机数生成器"指的是可能更迂腐地称为伪随机数生成器的生成器 - 生成器可以很好地模仿随机性,但完全算法,因此已知不是 "真正随机".任何这样的算法方法都会有一个"周期" - 它最终将开始重复.
Python的random模块使用了一个特别优秀且经过充分研究的伪随机生成器Mersenne Twister,其周期为2**19937-1- 当以十进制数字写出时,数字超过6千位,如len(str(2**19937-1))将确认;-).在我的笔记本电脑上,我每秒可以产生大约500万个这样的数字:
$ python -mtimeit -s'import random' 'random.random()'
1000000 loops, best of 3: 0.214 usec per loop
Run Code Online (Sandbox Code Playgroud)
假设一台更快的机器,能够每秒产生十亿个这样的数字,那么这个周期将需要大约10 5985年才能重复 - 并且宇宙时代的最佳当前估计值略低于1.5*10 12年.因此,几乎无法想象的宇宙生命周期达到重复的程度;-).使计算并行不会有太大帮助; 在宇宙中估计有大约10 80个原子,所以即使你能够在宇宙中的每个原子上运行这样的每秒十亿次的发生器,它仍然需要超过10 5800个宇宙寿命才能开始重复.
所以,你可能有理由怀疑这种对重复的担忧只是一个理论上的,而不是实际的问题;-).
然而,阶乘(计算长度为N的序列的排列)也增长得相当快.例如,Mersenne Twister 可能能够生成长度为2080的序列的所有排列,但绝对不是2081或更长的序列.如果不是"宇宙的一生"问题,那么文档对"即使是相当小的len(x)"的担心也是合理的 - 我们知道通过改造这样的伪RNG永远无法达到许多可能的排列一旦我们有一个相当长的序列,那么人们可能会担心我们实际上甚至在几次洗牌时会引入什么样的偏见!: - )
os.urandom调解对操作系统提供的任何物理随机源的访问--Windows上的CryptGenRandom,Linux上的/ dev/urandom等os.urandom提供了字节序列,但是在struct的帮助下,很容易将它们变成随机数:
>>> n = struct.calcsize('I')
>>> def s2i(s): return struct.unpack('I', s)[0]
...
>>> maxi = s2i(b'\xff'*n) + 1
>>> maxi = float(s2i(b'\xff'*n) + 1)
>>> def rnd(): return s2i(os.urandom(n))/maxi
Run Code Online (Sandbox Code Playgroud)
现在我们可以打电话random.shuffle(somelist, rnd)而不用担心偏见;-).
不幸的是,测量表明这种RNG方法比调用方法慢约50倍random.random()- 如果我们需要很多随机数,这可能是一个重要的实际考虑因素(如果我们不需要,可能会担心可能的偏差)被错放;-).该os.urandom方法也难以以可预测,可重复的方式使用(例如,用于测试目的),而random.random()您只需random.seed在测试开始时提供固定的初始值以保证可重现的行为.
因此,在实践中,os.urandom仅在您需要"加密质量"随机数时使用 - 确定的攻击者无法预测的随机数 - 因此愿意为使用它而不是支付实际价格random.random.
| 归档时间: |
|
| 查看次数: |
2453 次 |
| 最近记录: |