2009-12-25 114 views
1
random.shuffle(lst_shuffle, random.random) 

我知道后者是一个可选参数。但是它究竟做了什么。我不明白这是什么意思。 这是来自文档。什么是random.random做

random.random()¶ 返回下一个随机浮点数 数目在范围[0.0,1.0)。

我也看到这个,这个范围是0,0,0,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. 

回答

4

第二个参数用于指定要使用哪个随机数生成器。如果您需要/比“random.random”更好“,这可能很有用。对安全敏感的应用程序可能需要使用密码安全的随机数生成器。

random.randomrandom.random()之间的区别在于第一个是对产生简单随机数的函数的引用,第二个是实际调用该函数的引用。

如果你有其他的随机数生成器,你想用,你可以说

random.shuffle(x, my_random_number_function) 

至于什么random.random(默认生成器)是干什么的,它使用一种名为Mersenne twister创造一个看似算法随机浮点数在0和1之间(不包括1),该区间内的所有数字具有相同的可能性。

间隔从0到1只是一个约定。

0

该文档一直在说:

随机

可选参数是 0参数的函数在[0.0,1.0)返回一个随机 浮子;默认情况下,这个 是函数random()。

这意味着您可以指定自己的随机数生成器函数,也可以指示模块使用默认的random函数。第二个选项几乎总是最好的选择,因为Python使用了相当不错的PRNG。

它期望的函数应该返回一个在[0.0,1.0)范围内的浮点伪随机数,这意味着包含0.0,并且不包含1.0(即0.9999是要返回的有效数字,但是1.0不是)。理论上这个范围内的每个数字应该以相等的概率返回(即,这是一个线性分布)。

+0

嗨,我只是用一个额外的声明更新我的文章。所以我想这个额外的参数正好是1和0之间的概率(不包括1) – CppLearner 2009-12-25 15:41:24

+1

否,附加参数是返回伪随机数的**函数**,它本身不是数字。 Python允许函数作为参数传递到其他函数,这是一个很好的显示这样的能力 – 2009-12-25 15:44:02

0

随机函数取决于一个RNG(随机数发生器),默认为random.random。第二个参数是在那里,所以你可以提供你自己的RNG,而不是默认的。

UPDATE:

第二个参数是一个随机数发生器,在范围[0.0,1.0)每次调用时产生一个新的随机数。

下面是一个例子给你:

import random 

def a(): 
    return 0.0 

def b(): 
    return 0.999999999999 

arr = [1,2,3] 

random.shuffle(arr) 
print arr # prints [1, 3, 2] 

arr.sort() 
print arr # prints [1, 2, 3] 

random.shuffle(arr) 
print arr # prints [3, 2, 1] 

arr.sort() 
random.shuffle(arr, a) 
print arr # prints [2, 3, 1] 

arr.sort() 
random.shuffle(arr, a) 
print arr # prints [2, 3, 1] 

arr.sort() 
random.shuffle(arr, b) 
print arr # prints [1, 2, 3] 

arr.sort() 
random.shuffle(arr, b) 
print arr # prints [1, 2, 3] 

因此,如果函数总是返回相同的值,你总是得到相同的排列。如果函数每次调用都返回随机值,则会得到一个随机排列。

+0

嗨,我只是用一个额外的语句更新我的文章。所以我想这个额外的参数正好是1和0之间的概率(不包括1) – CppLearner 2009-12-25 15:40:44

0

example

>>> random.random()  # Random float x, 0.0 <= x < 1.0 
0.37444887175646646 

它产生在0和1

1

第二个参数之间的随机浮点数是被称为以产生依次用于随机数函数随机播放序列(第一个参数)。如果你不提供你自己的默认函数是random.random。

如果您想要自定义如何执行shuffle,您可能需要提供此参数。

而您的自定义功能将不得不返回范围[0.0,1.0) - 包括0.0,不包括1.0的数字。

5

现有答案在处理问题的具体问题方面做得很好,但我认为值得一提的是一个侧面问题:为什么你特别想要通过替代“随机生成器”到shuffle而不是其他的函数random模块。引述the docs

注意,对于即使相当小 LEN(x)中,的x的 排列的总数大于所述 期间最随机数 发生器较大;这意味着永远不会产生长序列的大部分排列 。

短语“随机数生成器”在这里指的是什么,可以更迂腐称为 -random数发生器 - 发电机,让随机性好模仿,但完全是算法,因此被称为不是是“真正的随机”。任何这样的算法都会有一个“时期” - 最终会开始重演。

Python的random模块采用了特别好的和充分研究的伪随机数发生器,该Mersenne Twister,用了一段2**19937-1 - 数字时在十进制数字写出有超过6000位数字,如len(str(2**19937-1))将确认;-)。在我的笔记本电脑,我可以每秒产生大约500万这样的数字:

$ python -mtimeit -s'import random' 'random.random()' 
1000000 loops, best of 3: 0.214 usec per loop 

假设更快的机器,能产生每秒十亿这样的数字,该周期将需要约10 年到重复 - 并且宇宙年龄的最佳当前估计值比1.5 * 10 年少。因此,宇宙生命周期几乎不可思议的达到重复的地步;-)。平行计算并没有多大帮助;估计宇宙中有大约10个原子,所以即使你能够在宇宙中的每个原子上运行这样一个每秒十亿次的发生器,它仍然需要超过10个宇宙 - 生活时间开始重复。

所以,你可能有理由怀疑这种担心重复是理论而非实际问题的一小部分;-)。尽管如此,因式分解(计算长度序列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 

现在,我们可以调用random.shuffle(somelist, rnd)和少担心偏见;-)。

不幸的是,测量表明,这种方法对于RNG比调用random.random()要慢50倍 - 如果我们需要很多随机数(这可能是一个重要的实际考虑因素(如果我们不需要,担心可能的偏见可能会错位;-)。 os.urandom方法也很难以可预测的,可重复的方式使用(例如,用于测试目的),而random.random()只需在测试开始时提供一个固定的初始random.seed以保证可重复的行为。

因此,在实践中,os.urandom仅用于需要“密码质量”随机数字 - 确定的攻击者无法预测的数字 - 因此愿意支付使用该数字的实际价格而不是random.random

+0

为了访问'os.urandom()','random'模块有一个'SystemRandom()'类,它的'.random()方法也可以在这里使用。 (我不知道这是3年前的情况......) – glglgl 2013-01-19 14:16:12

+0

Mersenne Twister的最大列表长度是2080年,而不是2081'2080! <=(2^19937-1)'但是'2081! <=(2^19937-1)'。我已经相应地编辑了这篇文章。 – 2017-05-21 14:49:46

相关问题