赞
踩
目录
2.2 random.seed() —— 记录与复现 (随机数种子)
2.3 random.randrange() / random.randint() —— 指定范围内生成伪随机数
2.4 random.choice() / random.choices() —— 对序列随机抽样
2.5 random.shuffle() —— 随机打乱序列顺序
2.6 random.sample() —— 对序列无重复随机抽样
给定相同的输入,大多数计算机程序每次都会生成相同的输出,它们因此被称作确定性的。然而,有时候我们并不需要这样的确定性,而是希望得到不可预知的随机结果。让程序具备真正意义上的非确定性并不容易,但还是是有办法使它至少看起来是不确定的。 其中之一是使用生成伪随机数 (pseudorandom) 的算法。伪随机数不是真正的随机数, 因为它们由一个确定性的计算生成,但是仅看其生成的数字,不可能将它们和随机生成的相区分开。
random 模块,顾名思义是与随机数操作相关的模块,它实现了各种分布的伪随机数生成器。但因为结果的完全确定性,它不适用于所有情况,特别是完全不适用于加密。以下将介绍一些常用功能。
random.random() 方法无需参数,调用后直接返回一个 [0.0, 1.0) 范围内的 float 型伪随机数,例如:
- import random # 导入 random 模块
-
- >>> random.random() # 获取一个伪随机数
- 0.3927174258393834
-
- >>> random.random() # 再获取一个伪随机数
- 0.5254320253344416
random.seed(a=None) 方法用于初始化随机数生成器,即生成或改变“随机数种子”。
若参数 a 被省略或为 None,则使用当前系统时间;若操作系统提供随机源,则使用操作系统随机源。
若参数 a 是 int 型数字,则直接使用。(现在 a 也可以是 float、string、bytes 等类型)
调用 random.random() 生成伪随机数时,每次生成的数都是随机的。但若预先调用 random.seed(a) 设好随机数种子后,再用 random.random() 将得到同一个伪随机数,从而确保“可复现”。例如:
- >>> random.random() # 不使用随机数种子, 获取未知随机数
- 0.9871512831697422
- >>> random.random() # 不使用随机数种子, 获取未知随机数
- 0.1582084156493
-
- >>> random.seed(1) # 设置一个随机数种子 1
- >>> random.random() # 获取随机数种子 1 的已知随机数
- 0.13436424411240122
-
- >>> random.random() # 不使用随机数种子, 仍获取未知随机数
- 0.8474337369372327
-
- >>> random.seed(1) # 再使用设好的随机数种子 1, 得到已知随机数
- >>> random.random()
- 0.13436424411240122
上述用法显而易见,当然,还存在一些不常见的用法:
- >>> random.seed('s') # 使用 string 设置 seed
- >>> random.random()
- 0.47702766547742415
-
- >>> random.seed(b'ss') # 使用 bytes 设置 seed
- >>> random.random()
- 0.8708725367892596
-
- >>> random.seed(1.2) # 使用 float 设置 seed
- >>> random.random()
- 0.24751702373640583
-
- >>> random.seed('s') # string 型复现
- >>> random.random()
- 0.47702766547742415
-
- >>> random.seed(b'ss') # bytes 型复现
- >>> random.random()
- 0.8708725367892596
-
- >>> random.seed(1.2) # float型复现
- >>> random.random()
- 0.24751702373640583
注意,只要没有多个线程运行,通过重新使用随机数种子值就能复现伪随机数。
random.randrange(stop) 相当于在 range(stop) 中随机输出一个 int 型数字。
random.randrange(start, stop[, step]) 同理相当于在 range(start, stop[, step]) 中随机输出一个 int 型数字。
上述方法类似于 range() 的位置参数匹配模式,而不应使用关键字参数,且实际上并未构建 range 对象。
- >>> random.randrange(6) # 指定 stop 参数测试
- 0
- >>> random.randrange(6)
- 3
-
- >>> random.randrange(1,6) # 指定 start, stop 参数测试
- 5
- >>> random.randrange(1,6)
- 4
-
- >>> random.randrange(1,6,3) # 指定 start, stop, step 参数测试
- 4
- >>> random.randrange(1,6,3)
- 1
random.randint(a, b) 返回 [a, b] 范围内的随机 int 数,相当于随机取 range(a, b+1) 中的一数输出。
- >>> random.randint(1,6)
- 1
- >>> random.randint(1,6)
- 6
random.choice(seq) 从非空序列 seq 返回一个随机元素。若 seq 为空将抛出 IndexError 。
- >>> random.choice(['a', 'k', '4', '7', 6]) # seq 为 list
- 'k'
- >>> random.choice(['a', 'k', '4', '7', 6])
- 6
-
- >>> random.choice(('m', '4', 'a', '1', 1)) # seq 为 tuple
- 'm'
- >>> random.choice(('m', '4', 'a', '1', 1))
- 'a'
-
- >>> random.choice('csgo') # seq 为 string
- 'c'
- >>> random.choice('csgo')
- 'g'
random.choices(population, weights=None, *, cum_weights=None, k=1) 从序列 population 随机返回长度为 k 的元素 list。 若 population 为空将抛出 IndexError 。
注意指定输出长度 k 要使用关键字参数。
- >>> random.choices(['a', 'k', '4', '7', 6]) # 默认返回长度 k=1 的 list
- ['a']
- >>> random.choices(['a', 'k', '4', '7', 6])
- [6]
- >>> random.choices(['a', 'k', '4', '7', 6], k=2) # 若要指定返回 list 长度需用关键字参数
- ['4', 'a']
- >>> random.choices(['a', 'k', '4', '7', 6], k=2)
- ['a', 'k']
若指定相对权重序列 weight,则根据相对权重选择;若指定累积权重序列 cum_weights,则根据累积权重选择。
权重序列必须与序列 population 等长,因为它与序列 population 各元素输出概率成正比。例如,相对权重 [10, 5, 30, 5] 相当于百分制的累积权重 [10, 15, 45, 50]。在内部,相对权重在选择前会转换为累积权重,因此直接提供累积权重可节省计算量。
注意指定权重需用关键字参数;若不指定任何权重,则等概率选择。
- >>> random.choices(['a', 'k', '4', '7', 6], cum_weights=[1,2,3,4,5],k=2)
- ['a', '4']
- >>> random.choices(['a', 'k', '4', '7', 6], weights=[1,2,3,4,5],k=2)
- ['k', '4']
- >>> random.choices(['a', 'k', '4', '7', 6], weights=[0.1,0.2,0.3,0.4,0.5],k=2)
- [6, 6]
- >>> random.choices(['a', 'k', '4', '7', 6], cum_weights=[10,20,30,40,0],k=2)
- ['7', '7']
random.shuffle(x[, random]) 打乱序列 x 的元素位置。注意,这是就地 (in-place) 重洗数据,以节省空间。
- >>> _list = ['a', 'k', '4', '7', 6] # 以 list 为例
- >>> random.shuffle(_list)
- >>> _list
- [6, 'a', '4', 'k', '7']
random.sample(population, k) 从序列或集合 population 中返回长度为 k 的 list,而不会改变原序列或集合 population,常用于无重复随机抽样。换言之,每次从 population 中选中用于输出的元素不会被再次选到。
- >>> x = [1,1,2,2,3,3,4,4]
- >>> random.sample(x,4)
- [2, 3, 4, 3]
- >>> random.sample(x,8)
- [2, 1, 4, 1, 2, 3, 4, 3]
random.uniform(a, b) 返回一个随机 float 数 N 。若 a ≤ b,则 a ≤ N ≤ b;若 a > b 时,则 b ≤ N ≤ a 。
- >>> random.uniform(1,6)
- 2.360764594102883
- >>> random.uniform(6,1)
- 1.1694993454817864
random.triangular(low, high, mode) 返回一个随机 float 数 N,满足 low ≤ N ≤ high,并在这些边界间使用指定的 mode 。
默认边界 low=0,high=1。mode 参数默认为边界间的中点,给出对称分布。
- >>> random.triangular()
- 0.7901206686668583
- >>> random.triangular(1,3)
- 2.2824148437047245
random.betavariate(alpha, beta) 按 beta 分布返回 float 数,范围 0 ~ 1,要求参数 alpha>0,beta>0 。
- >>> random.betavariate(1,2)
- 0.0002116366994341509
- >>> random.betavariate(6,7)
- 0.4745896776730147
random.expovariate(lambd) 按指数分布返回 float 数,参数 lambd 是 1.0 除以所需的平均值,应为非零数。
(该参数本应命名为 “lambda” ,但这是 Python 中的保留字)
若 lambd 为正,则返回值范围为 0 ~ +∞;若 lambd 为负,则返回值范围为 -∞ ~ 0 。
- >>> random.expovariate(1)
- 0.1350680972867813
- >>> random.expovariate(-1)
- -2.05439953632068
random.gammavariate(alpha, beta) 按 gamma 分布 (不是 gamma 函数) 返回 float 数,要求参数 alpha>0,beta>0。
random.gauss(mu, sigma) 按高斯 (gauss) 分布返回 float 数,mu 是平均值,sigma 是标准差。
这比 random.normalvariate() 略快。
random.lognorrmvariate(mu, sigma) 按对数正态分布返回 float 数。mu 是平均值,可为任意值;sigma 是标准差,须大于0。若采用该分布的自然对数,将得到一个正态分布。
random.normalvariate(mu, sigma) 按正态分布返回 float 数,mu 是平均值,sigma 是标准差。
random.vonmisesvariate(mu, kappa) 按冯·米塞斯 (von Mises) 分布返回 float 数, mu 是平均角度,以弧度表示,介于 0~ 2π 之间;kappa 是浓度参数,必须大于等于 0。 若 kappa 等于 0,则该分布在 0~ 2π 的范围内减小到均匀的随机角度。
random.paretovariate(alpha) 按帕累托分布返回 float 数,alpha 是形状参数.
random.weibullvariate(alpha, beta) 按威布尔分布返回 float 数,alpha 是比例参数,beta 是形状参数。
参考文献:
《Think Python》
https://docs.python.org/zh-cn/3.6/library/random.html?highlight=random%20模块#module-random
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。