python随机数模块random

random是python的一个内置模块,专门用于生成随机数,但是要明确一点,random模块生成的并非真正的随机数,而是伪随机数。random提供的部分方法可以生成指定分布的随机数,比如生成符合高斯分布的随机数,这些方法在处理数学问题时将非常有用。

1. 随机数种子

random模块生成的都是伪随机数,具体生成的随机数是什么取决于随机数种子,当随机数种子相同时,生成的随机数也就相同。使用seed方法可设置随机数种子。

import random

random.seed(5)
print(random.randint(1, 100))           # 80

这段代码,不论谁执行,在哪里执行,生成的随机数都是80,因为随机数种子都是5,如果使用seed方法设置随机数种子或者seed方法在调用时不传参数,则使用系统当前的时间来作为随机数种子,这也是我们平常所采用的方法,不设置随机数种子。

某些情况下设置随机数种子,是为了让某个包含了随机数的算法能够有相同的结果,这样便于验证算法的正确性。

2. 生成指定分布的随机数

random模块的一些方法可以生成符合指定分布的随机数,比如random.gauss

def gauss(self, mu, sigma):
  • mu 是平均值
  • sigma 是标准差

下面的代码生成10000个符合平均值为3标准为1的随机数并绘制出直方图。

import random
import matplotlib.pyplot as plt


nums = []
for i in range(10000):
    value = random.gauss(3, 1)
    nums.append(value)

plt.hist(nums, bins=200)
plt.show()

random

除了高斯分布以外,random还支持生成指数分布,Gamma 分布等其他分布的随机数,在实践中,这类方法极少使用,因此不做过多介绍。

3. 随机生成整数的方法

3.1 random.randint(a, b)

random.randint方法返回一个随机整数N,N满足条件a <= N <= b

>>> import random
>>> random.randint(0, 100)
70

3.2 random.randrange

random.randrange方法的应用与内置函数range有一点关联,randrange会从range函数返回的整数序列中随机返回一个整数。

random.randrange方法语法

random.randrange(stop)
random.randrange(start, stop[, step])

range(stop)产生一个从0到stop-1的整数序列seq,random.randrange(stop)从seq里随机选择一个数做为返回值,random.randrange(stop)等价于random.randint(0, stop-1)。

range(start, stop[, step]) 以step为步长从start开始到stop结束产生一个序列seq,random.randrange(start, stop[, step])从seq里随机选择一个数做为返回值。

示例代码

>>> random.randrange(100)
47
>>> random.randrange(0, 100, 3)
21
>>> random.randrange(0, 100, 3)
81

3.3 random.getrandbits(k)

random.getrandbits(k)返回具有k个比特位的随机非负整数,以random.getrandbits(3)为例,一个整数有3个比特位,那么最大值的二进制形式为111,最小值的二进制形式为000,转换为10进制,随机数最大值是7,最小值是0。

>>> random.getrandbits(3)
7
>>> random.getrandbits(3)
3
>>> random.getrandbits(3)
2
>>> random.getrandbits(3)
1
>>> random.getrandbits(3)
3
>>> random.getrandbits(3)
2
>>> random.getrandbits(3)
0
>>> random.getrandbits(3)
5

4. 生成随机浮点数

4.1 random.random()

random.random()方法返回一个在 [0.0, 1.0)范围内的浮点数,示例代码

>>> import random
>>> random.random()
0.4682406396257134

4.2 random.uniform(a, b)

random.uniform 方法返回一个随机数N,当a <= b时,N满足条件a <= N <= b, 当a > b时,N满足条件b <= N <= a

>>> random.uniform(1.2, 4.5)
3.344709736336089
>>> random.uniform(4.5, 1.2)
1.26233857205222
>>> random.uniform(4.5, 4.5)
4.5

uniform 对a,b两个参数的大小关系没有要求,通常人们会猜测a应当小于等于b,但实际上a可以大于b。

5. 从序列里随机选取对象

5.1 random.choice(seq)

random.choice方法从序列seq中随机返回一个对象,如果序列为空,则引发IndexError

>>> random.choice([1, 4, 5, 6])
4

5.2 random.choices

random.choices方法语法

random.choices(population, weights=None, *, cum_weights=None, k=1)

random.choices方法从序列population中随机选取k个对象,如果指定了weights,则根据权重返回对象,权重越大,被随机选中返回的概率越大。返回的k个随机对象可以有重复对象,这一点一定要注意。

参数解释

  • population 序列
  • weights 相对权重
  • cum_weights 累积权重
  • k,返回对象的个数

示例代码
不设置权重

import random

fruits = ['苹果', '香蕉', '火龙果', '葡萄']
lst = random.choices(fruits, k=2)
print(lst)      # ['香蕉', '葡萄']

设置相对权重

import random

fruits = ['苹果', '香蕉', '火龙果', '葡萄']
lst = random.choices(fruits, weights=[5, 2, 2, 1], k=2)
print(lst)   # ['苹果', '火龙果']

weights里的对象个数必须与fruits里的对象个数相同,weights表示的是各项之间被选中的概率相对比值,苹果被随机选中的概率是50%,计算方法是5/(5+2+2+1)。

设置累积权重

import random

fruits = ['苹果', '香蕉', '火龙果', '葡萄']
lst = random.choices(fruits, cum_weights=[5, 7, 9, 10], k=2)
print(lst)   # ['苹果', '火龙果']

choices 在处理权重时,会自动将相对权重转换为累积权重,weights=[5, 2, 2, 1]转为为累积权重为cum_weights=[5, 7, 9, 10],每一项的值都是前面几项的和。

累积权重不如相对权重好理解,所以建议你使用相对权重。

5.3 random.sample

random.sample方法从序列中随机选取k个对象,选出的对象都是唯一的,sample用于无重复的随机抽样,smaple方法语法

def sample(self, population, k):

参数说明

  • population 序列
  • k 抽样个数

如果population本身就包含了重复元素,sample方法每次返回的对象都是样本中可能的选择。

import random

fruits = ['苹果', '香蕉', '火龙果', '葡萄']
lst = random.sample(fruits, k=2)
print(lst)   # ['香蕉', '火龙果']

5.4 random.shuffle

random.shuffle方法将序列就地大乱,这类似于我们娱乐时的洗牌。

import random

lst = [i for i in range(10)]
random.shuffle(lst)
print(lst)   # [2, 8, 4, 3, 9, 1, 6, 0, 5, 7]

经shuffle方法处理后,lst列表变得无序。

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案