Random:伪随机数生成器

random模块基于Mersenne Twister算法提供了一个快速伪随机数生成器,原先开发这个生成器是为了向蒙特卡洛模拟生成输出,Mersenne Twister算法会生成大周期近均匀分布的数,因此适用于大量不同类型的应用

继承树

_random.Random(builtins.object)
Random
SystemRandom

生成随机数

random()

random(),random() -> x in the interval [0, 1)

random()函数从所生成的序列返回下一个随机的浮点值,返回的所有值都落在 0≤n<1.0 区间内

import random

for i in range(10):
    print('%.3f' % random.random(), end='  ')
    
# 0.905  0.541  0.897  0.384  0.732  0.419  0.949  0.500  0.365  0.232 
uniform()

uniform(a, b),Get a random number in the range [a, b) or [a, b] depending on rounding

使用uniform()函数会生成一个指定区间的数,在uniform()函数中传入最大值和最小值,uniform()会使用公式来调整random()的返回值

公式:min + ( max - min ) * random()

import random

for i in range(10):
    print('%.1f' % random.uniform(1, 2), end='  ')
# 53.660  68.371  35.115  61.124  5.931  81.609  89.923  3.352  41.802  41.302

for i in range(10):
    print('%.1f' % random.uniform(1, 2), end='  ')
# 1.0  1.5  1.8  1.7  1.7  2.0  1.0  1.4  1.2  1.1  

指定种子

seed()

seed(a=None, version=2),Initialize internal state from hashable object

None or no argument seeds from current time or from an operating system specific randomness source if available

If *a* is an int, all bits are used

For version 2 (the default), all of the bits are used if a is a str, bytes, or bytearray. For version 1 (provided for reproducing random sequences from older versions of Python), the algorithm for str and bytes generates a narrower range of seeds

每一次调用random()函数都会生成不同的值,并且在一个非常大的周期之后数字才会重复

seed()函数可以用来初始化伪随机数生成器,使它生成一个期望的值集

import random

# 参数为任意可哈希类型的对象
random.seed((1))

for i in range(10):
    print('%.3f' % random.uniform(1, 100), end='  ')

# 多次运行后其结果相同
# 14.302  84.896  76.614  26.252  50.048  45.500  65.508  79.084  10.292  3.806
# 14.302  84.896  76.614  26.252  50.048  45.500  65.508  79.084  10.292  3.806

print('\n')

for i in range(10):
    print('%.3f' % random.uniform(1, 100), end='  ')
    
# 83.741  43.844  76.466  1.208  45.093  72.432  23.647  94.582  90.241  4.028 
# 83.741  43.844  76.466  1.208  45.093  72.432  23.647  94.582  90.241  4.028 

种子(seed)值会控制由公式生成的第一个值,该公式可用来生成伪随机数,由于该公式是确定的,所以改变种子后便设置了将要生成的整个序列,seed()参数可以是任意散列(可哈希)对象,默认使用一个平台特定的随机源(如果有的话),如果没有随机源,则使用当前时间

保存状态

random()使用的伪随机数算法的内部状态可以保存,并用于控制后续生成的随机数,使用getstate()会返回数据的实现细节,以后可借助setstate()函数并利用getstate()返回的数据重新初始化伪随机数生成器

getstate()

getstate(),Return internal state; can be passed to setstate() later

setstate()

setstate(state),Restore internal state from object returned by getstate()

import random

for i in range(10):
    print('%.3f' % random.random(), end='  ')
print('\n')
# 0.416  0.970  0.960  0.600  0.121  0.006  0.813  0.834  0.145  0.757 

# 保存初始化状态
state = random.getstate()

for i in range(10):
    print('%.3f' % random.random(), end='  ')
print('\n')

for i in range(10):
    print('%.3f' % random.random(), end='  ')
print('\n')

for i in range(10):
    print('%.3f' % random.random(), end='  ')
print('\n')

# 0.754  0.289  0.327  0.914  0.482  0.084  0.701  0.393  0.808  0.811
# 0.535  0.038  0.209  0.128  0.124  0.102  0.108  0.204  0.668  0.201
# 0.826  0.191  0.248  0.015  0.725  0.830  0.468  0.587  0.581  0.421


# 重新设置初始化状态
random.setstate(state)
for i in range(10):
    print('%.3f' % random.random(), end='  ')
print('\n')

for i in range(10):
    print('%.3f' % random.random(), end='  ')
print('\n')

for i in range(10):
    print('%.3f' % random.random(), end='  ')
print('\n')

# 0.754  0.289  0.327  0.914  0.482  0.084  0.701  0.393  0.808  0.811
# 0.535  0.038  0.209  0.128  0.124  0.102  0.108  0.204  0.668  0.201
# 0.826  0.191  0.248  0.015  0.725  0.830  0.468  0.587  0.581  0.421

# 再次重新初始化状态
random.setstate(state)
for i in range(10):
    print('%.3f' % random.random(), end='  ')
print('\n')

for i in range(10):
    print('%.3f' % random.random(), end='  ')
print('\n')

for i in range(10):
    print('%.3f' % random.random(), end='  ')
print('\n')

# 0.754  0.289  0.327  0.914  0.482  0.084  0.701  0.393  0.808  0.811
# 0.535  0.038  0.209  0.128  0.124  0.102  0.108  0.204  0.668  0.201
# 0.826  0.191  0.248  0.015  0.725  0.830  0.468  0.587  0.581  0.421

随机整数

randint()

randint(a, b),Return random integer in range [a, b], including both end points

randint()的参数是值的闭区间的两端,可以为负数,第一个参数的值要小于第二个参数

randrange()

randrange(start, stop=None, step=1, _int=<class ‘int’>),Choose a random item from range(start, stop[, step])

This fixes the problem with randint() which includes the endpoint; in Python this is usually not what you want

randrange()支持步长参数,所以完全等价于range(start, stop, step)选择一个随机值,但randrange()更加高效,因为它并不真正构建区间

import random

for i in range(5):
    print(random.randint(1, 4), end='  ')
print('\n')
# 结果包含端点值
# 1  1  1  4  2  

for i in range(5):
    print(random.randrange(1, 4), end='  ')

# 结果不包含端点值
# 3  2  2  1  3  

选择随机元素

choice()

choice(seq),Choose a random element from a non-empty sequence

choice()函数可以从一个序列中随机选择

import random


# 模拟抛硬币
outcomes = {'正面' : 0, '反面' : 0}
sides = list(outcomes.keys())

for i in range(10000):
    # 随机选择字典中的一个key对其进行加一,表示选择了硬币的哪一面
    outcomes[random.choice(sides)] += 1

print('正面', outcomes['正面'])
print('反面', outcomes['反面'])

# 正面 5095
# 反面 4905

洗牌

shuffle()

shuffle(x, random=None),Shuffle list x in place, and return None

Optional argument random is a 0-argument function returning a random float in [0.0, 1.0); if it is the default None, the standard random.random will be used

将一个列表中的值打乱,即洗牌

import random

lst = [1, 2, 3, 4, 5, 6, 7, 8, 9]

random.shuffle(lst)
print(lst)

# [9, 7, 4, 3, 2, 8, 1, 5, 6]

采样

sample()

sample(population, k),Chooses k unique random elements from a population sequence or set

sample()函数可以生成无重复值的样本,并且不会修改输入序列

sample()函数的生成结果集算法会考虑输入的规模和请求的样本,从而尽可能高效地生成结果

import random

lst = [i for i in range(1, 21)]
print(lst)
# [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

# 随机抽取列表中的10个值
print(random.sample(lst, 10))
# [15, 4, 17, 5, 20, 9, 7, 10, 13, 3]

# 取值的个数超过原列表范围
print(random.sample(lst, 21))
# ValueError: Sample larger than population or is negative

多个并发生成器

random模块下包含一个Random类以管理多个随机数生成器的内部状态,上面的函数均可以作为Random实例的方法得到,并且每个实例都可以被单独初始化和使用,不会干扰其他实例的返回值

import random

r1 = random.Random()
r2 = random.Random()

for i in range(5):
    print('%.3f' % r1.random(), end='  ')
print('\n')
# 0.937  0.973  0.715  0.231  0.355

for i in range(5):
    print('%.3f' % r2.random(), end='  ')
print('\n')
# 0.292  0.933  0.125  0.387  0.047

# 设置相同的种子
r1.seed(1)
r2.seed(1)

for i in range(5):
    print('%.3f' % r1.random(), end='  ')
print('\n')
# 0.134  0.847  0.764  0.255  0.495 

for i in range(5):
    print('%.3f' % r2.random(), end='  ')
print('\n')
# 0.134  0.847  0.764  0.255  0.495 

SystemRandom

有些操纵系统提供了一个随机数生成器,可以访问更多能引入生成器的信息源,random通过SystemRandom类提供该特性,SystemRandom类与Random类的API相同,不过使用os.urandom()生成值,该值会构成所有其他算法的基础

SystemRandom产生的序列是不可再生的,因为其随机性来自系统,而非软件状态,即seed()和setstate()不会起作用

import random

r1 = random.SystemRandom()
r2 = random.SystemRandom()

for i in range(5):
    print(r1.randint(1, 100), end='  ')
print('\n')
# 83  31  44  12  56  

for i in range(5):
    print(r1.randint(1, 100), end='  ')
print('\n')
# 70  76  55  90  82  

# 设置相同的种子值
r1.seed(1)
r2.seed(1)

for i in range(5):
    print(r1.randint(1, 100), end='  ')
print('\n')
# 93  14  78  79  38  


for i in range(5):
    print(r1.randint(1, 100), end='  ')
print('\n')
# 36  1  44  20  41 

非均匀分布

random()生成的值为均匀分布

random模块中包含一些函数以生成非均匀分布的值,可实现的分布:

  • 正态分布
  • 近似分布
  • 指数分布
  • 角分布
  • 大小分布
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值