当前位置:   article > 正文

【Python】详解 random 模块_python random.seed randint random 坑

python random.seed randint random 坑

目录

一、绪论

二、说明

2.1 random.random() —— 获取伪随机数

2.2 random.seed() —— 记录与复现 (随机数种子)

2.3 random.randrange() / random.randint() —— 指定范围内生成伪随机数

2.4 random.choice() / random.choices() —— 对序列随机抽样

2.5 random.shuffle() —— 随机打乱序列顺序

2.6 random.sample() —— 对序列无重复随机抽样

2.7 各类概率分布


一、绪论

给定相同的输入,大多数计算机程序每次都会生成相同的输出,它们因此被称作确定性的。然而,有时候我们并不需要这样的确定性,而是希望得到不可预知的随机结果。让程序具备真正意义上的非确定性并不容易,但还是是有办法使它至少看起来是不确定的。 其中之一是使用生成伪随机数 (pseudorandom) 的算法。伪随机数不是真正的随机数, 因为它们由一个确定性的计算生成,但是仅看其生成的数字,不可能将它们和随机生成的相区分开。

random 模块,顾名思义是与随机数操作相关的模块,它实现了各种分布的伪随机数生成器。但因为结果的完全确定性,它不适用于所有情况,特别是完全不适用于加密。以下将介绍一些常用功能。


二、说明

2.1 random.random() —— 获取伪随机数

random.random() 方法无需参数,调用后直接返回一个 [0.0, 1.0) 范围内的 float 型伪随机数,例如:

  1. import random # 导入 random 模块
  2. >>> random.random() # 获取一个伪随机数
  3. 0.3927174258393834
  4. >>> random.random() # 再获取一个伪随机数
  5. 0.5254320253344416

2.2 random.seed() —— 记录与复现 (随机数种子)

random.seed(a=None) 方法用于初始化随机数生成器,即生成或改变“随机数种子”。

若参数 a 被省略或为 None,则使用当前系统时间;若操作系统提供随机源,则使用操作系统随机源。

若参数 a 是 int 型数字,则直接使用。(现在 a 也可以是 float、string、bytes 等类型)

调用 random.random() 生成伪随机数时,每次生成的数都是随机的。但若预先调用 random.seed(a) 设好随机数种子后,再用 random.random() 将得到同一个伪随机数,从而确保“可复现”。例如:

  1. >>> random.random() # 不使用随机数种子, 获取未知随机数
  2. 0.9871512831697422
  3. >>> random.random() # 不使用随机数种子, 获取未知随机数
  4. 0.1582084156493
  5. >>> random.seed(1) # 设置一个随机数种子 1
  6. >>> random.random() # 获取随机数种子 1 的已知随机数
  7. 0.13436424411240122
  8. >>> random.random() # 不使用随机数种子, 仍获取未知随机数
  9. 0.8474337369372327
  10. >>> random.seed(1) # 再使用设好的随机数种子 1, 得到已知随机数
  11. >>> random.random()
  12. 0.13436424411240122

上述用法显而易见,当然,还存在一些不常见的用法:

  1. >>> random.seed('s') # 使用 string 设置 seed
  2. >>> random.random()
  3. 0.47702766547742415
  4. >>> random.seed(b'ss') # 使用 bytes 设置 seed
  5. >>> random.random()
  6. 0.8708725367892596
  7. >>> random.seed(1.2) # 使用 float 设置 seed
  8. >>> random.random()
  9. 0.24751702373640583
  10. >>> random.seed('s') # string 型复现
  11. >>> random.random()
  12. 0.47702766547742415
  13. >>> random.seed(b'ss') # bytes 型复现
  14. >>> random.random()
  15. 0.8708725367892596
  16. >>> random.seed(1.2) # float型复现
  17. >>> random.random()
  18. 0.24751702373640583

注意,只要没有多个线程运行,通过重新使用随机数种子值就能复现伪随机数。

2.3 random.randrange() / random.randint() —— 指定范围内生成伪随机数

random.randrange(stop) 相当于在 range(stop) 中随机输出一个 int 型数字。

random.randrange(start, stop[, step]) 同理相当于在 range(start, stop[, step]) 中随机输出一个 int 型数字。

上述方法类似于 range() 的位置参数匹配模式,而不应使用关键字参数,且实际上并未构建 range 对象。

  1. >>> random.randrange(6) # 指定 stop 参数测试
  2. 0
  3. >>> random.randrange(6)
  4. 3
  5. >>> random.randrange(1,6) # 指定 start, stop 参数测试
  6. 5
  7. >>> random.randrange(1,6)
  8. 4
  9. >>> random.randrange(1,6,3) # 指定 start, stop, step 参数测试
  10. 4
  11. >>> random.randrange(1,6,3)
  12. 1

random.randint(a, b) 返回 [a, b] 范围内的随机 int 数,相当于随机取 range(a, b+1) 中的一数输出。

  1. >>> random.randint(1,6)
  2. 1
  3. >>> random.randint(1,6)
  4. 6

2.4 random.choice() / random.choices() —— 对序列随机抽样

random.choice(seq) 从非空序列 seq 返回一个随机元素。若 seq 为空将抛出 IndexError 。

  1. >>> random.choice(['a', 'k', '4', '7', 6]) # seq 为 list
  2. 'k'
  3. >>> random.choice(['a', 'k', '4', '7', 6])
  4. 6
  5. >>> random.choice(('m', '4', 'a', '1', 1)) # seq 为 tuple
  6. 'm'
  7. >>> random.choice(('m', '4', 'a', '1', 1))
  8. 'a'
  9. >>> random.choice('csgo') # seq 为 string
  10. 'c'
  11. >>> random.choice('csgo')
  12. 'g'

random.choices(populationweights=None*cum_weights=Nonek=1) 从序列 population 随机返回长度为 k 的元素 list。 若 population 为空将抛出 IndexError 。

注意指定输出长度 k 要使用关键字参数

  1. >>> random.choices(['a', 'k', '4', '7', 6]) # 默认返回长度 k=1 的 list
  2. ['a']
  3. >>> random.choices(['a', 'k', '4', '7', 6])
  4. [6]
  5. >>> random.choices(['a', 'k', '4', '7', 6], k=2) # 若要指定返回 list 长度需用关键字参数
  6. ['4', 'a']
  7. >>> random.choices(['a', 'k', '4', '7', 6], k=2)
  8. ['a', 'k']

若指定相对权重序列 weight,则根据相对权重选择;若指定累积权重序列 cum_weights,则根据累积权重选择。

权重序列必须与序列 population 等长,因为它与序列 population 各元素输出概率成正比。例如,相对权重 [10, 5, 30, 5] 相当于百分制的累积权重 [10, 15, 45, 50]。在内部,相对权重在选择前会转换为累积权重,因此直接提供累积权重可节省计算量。

注意指定权重需用关键字参数;若不指定任何权重,则等概率选择。 

  1. >>> random.choices(['a', 'k', '4', '7', 6], cum_weights=[1,2,3,4,5],k=2)
  2. ['a', '4']
  3. >>> random.choices(['a', 'k', '4', '7', 6], weights=[1,2,3,4,5],k=2)
  4. ['k', '4']
  5. >>> random.choices(['a', 'k', '4', '7', 6], weights=[0.1,0.2,0.3,0.4,0.5],k=2)
  6. [6, 6]
  7. >>> random.choices(['a', 'k', '4', '7', 6], cum_weights=[10,20,30,40,0],k=2)
  8. ['7', '7']

2.5 random.shuffle() —— 随机打乱序列顺序

random.shuffle(x[, random]) 打乱序列 x 的元素位置。注意,这是就地 (in-place) 重洗数据,以节省空间。

  1. >>> _list = ['a', 'k', '4', '7', 6] # 以 list 为例
  2. >>> random.shuffle(_list)
  3. >>> _list
  4. [6, 'a', '4', 'k', '7']

2.6 random.sample() —— 对序列无重复随机抽样

random.sample(populationk) 从序列或集合 population 中返回长度为 k 的 list,而不会改变原序列或集合 population,常用于无重复随机抽样。换言之,每次从 population 中选中用于输出的元素不会被再次选到。

  1. >>> x = [1,1,2,2,3,3,4,4]
  2. >>> random.sample(x,4)
  3. [2, 3, 4, 3]
  4. >>> random.sample(x,8)
  5. [2, 1, 4, 1, 2, 3, 4, 3]

2.7 各类概率分布

random.uniform(a, b) 返回一个随机 float 数 N 。若 a ≤ b,则 a ≤ N ≤ b;若 a > b 时,则 b ≤ N ≤ a 。

  1. >>> random.uniform(1,6)
  2. 2.360764594102883
  3. >>> random.uniform(6,1)
  4. 1.1694993454817864

random.triangular(lowhighmode) 返回一个随机 float 数 N,满足 low ≤ N ≤ high,并在这些边界间使用指定的 mode 。

默认边界 low=0,high=1。mode 参数默认为边界间的中点,给出对称分布。

  1. >>> random.triangular()
  2. 0.7901206686668583
  3. >>> random.triangular(1,3)
  4. 2.2824148437047245

random.betavariate(alphabeta) 按 beta 分布返回 float 数,范围 0 ~ 1,要求参数 alpha>0,beta>0 。

  1. >>> random.betavariate(1,2)
  2. 0.0002116366994341509
  3. >>> random.betavariate(6,7)
  4. 0.4745896776730147

random.expovariate(lambd) 按指数分布返回 float 数,参数 lambd 是 1.0 除以所需的平均值,应为非零数。

(该参数本应命名为 “lambda” ,但这是 Python 中的保留字)

若 lambd 为正,则返回值范围为 0 ~ +∞;若 lambd 为负,则返回值范围为 -∞ ~ 0 。

  1. >>> random.expovariate(1)
  2. 0.1350680972867813
  3. >>> random.expovariate(-1)
  4. -2.05439953632068

random.gammavariate(alphabeta) 按 gamma 分布 (不是 gamma 函数) 返回 float 数,要求参数 alpha>0,beta>0。

random.gauss(mu, sigma按高斯 (gauss) 分布返回 float 数,mu 是平均值,sigma 是标准差。

这比 random.normalvariate() 略快。

random.lognorrmvariate(musigma按对数正态分布返回 float 数。mu 是平均值,可为任意值;sigma 是标准差,须大于0。若采用该分布的自然对数,将得到一个正态分布。

random.normalvariate(musigma按正态分布返回 float 数,mu 是平均值,sigma 是标准差。

random.vonmisesvariate(mukappa) 按冯·米塞斯 (von Mises) 分布返回 float 数, mu 是平均角度,以弧度表示,介于 0~ 2π 之间;kappa 是浓度参数,必须大于等于 0。 若 kappa 等于 0,则该分布在 0~ 2π 的范围内减小到均匀的随机角度。

random.paretovariate(alpha按帕累托分布返回 float 数,alpha 是形状参数.

random.weibullvariate(alphabeta按威布尔分布返回 float 数,alpha 是比例参数,beta 是形状参数。


参考文献:

《Think Python》

https://docs.python.org/zh-cn/3.6/library/random.html?highlight=random%20模块#module-random

Python seed() 函数 | 菜鸟教程

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/966152
推荐阅读
相关标签
  

闽ICP备14008679号