random 模块是 Python 标准库中用于生成伪随机数的核心模块。它提供了多种函数用于生成随机数、进行随机选择、打乱序列等操作。理解其工作原理和正确使用它至关重要。
1. 核心概念:伪随机数
首先要明白,random 模块生成的是伪随机数。
- 真随机数:通过物理现象(如电子元件的噪声、放射性衰变等)产生,完全不可预测。
- 伪随机数:由一个确定的、可重复的算法(通常是伪随机数生成器,PRNG)根据一个初始值(称为种子,Seed)计算出来的数列。这个数列在统计上看起来是随机的,但只要种子相同,生成的数列就完全相同。
为什么使用伪随机数?
因为计算机是确定性系统,没有真正的随机源。伪随机数具有可重现性,这在程序调试和复现结果时非常有用。
2. 模块的导入
使用前必须先导入模块:
import random3. 常用函数详解
3.1 初始化与种子 (Seed)
random.seed(a=None, version=2)
- 作用:初始化伪随机数生成器。这是所有随机操作的起点。
- 参数:
a:种子值。可以是int,float,str,bytes,bytearray等。如果a被省略或为None,则使用当前系统时间(默认行为)。version:通常使用默认值 2。
- 为什么使用? 设置相同的种子可以保证每次运行程序都能得到相同的“随机”结果,便于调试和实验复现。
示例:
random.seed(42) # 设置种子为 42
print(random.random()) # 每次运行都会输出 0.6394267984578837
random.seed(42) # 再次设置相同的种子
print(random.random()) # 再次输出 0.6394267984578837
random.seed() # 使用系统时间作为种子,每次运行结果都不同
print(random.random())3.2 基本随机数生成
random.random()
- 作用:返回一个
[0.0, 1.0)范围内的随机浮点数。这是最基础、最常用的函数。
random.uniform(a, b)
- 作用:返回一个
[a, b](或[b, a],如果b < a)范围内的随机浮点数。
random.randrange(stop)random.randrange(start, stop[, step])
- 作用:从
range(start, stop, step)中随机选择一个整数。类似于choice(range(start, stop, step)),但更高效。 - 示例:
random.randrange(10)生成0-9的整数;random.randrange(1, 11, 2)生成1, 3, 5, 7, 9中的一个。
random.randint(a, b)
- 作用:返回一个
[a, b]范围内的随机整数。等价于random.randrange(a, b+1)。
3.3 序列操作
random.choice(seq)
- 作用:从非空序列
seq(如list,tuple,str)中随机返回一个元素。 - 示例:
random.choice(['rock', 'paper', 'scissors'])
random.choices(population, weights=None, *, cum_weights=None, k=1)
- 作用:从
population中有放回地随机抽取k次,返回一个大小为k的列表。 - 参数:
weights:相对权重列表(例如[10, 1, 1])。cum_weights:累积权重列表(例如[10, 11, 12])。k:抽样次数。
- 示例:模拟不公平骰子
random.choices([1,2,3,4,5,6], weights=[0.1, 0.1, 0.1, 0.1, 0.1, 0.5], k=10)
random.sample(population, k, *, counts=None)
- 作用:从
population中无放回地随机抽取k个唯一的元素,返回一个新列表。适用于抽奖、洗牌前抽取部分牌等场景。 - 示例:从 100 人中抽取 5 个幸运观众
winners = random.sample(range(100), 5)
random.shuffle(x[, random])
- 作用:将序列
x原地打乱(直接修改原序列)。只能用于可变序列(如列表),不能用于不可变序列(如元组、字符串)。 - 示例:
cards = ['A', '2', '3', 'K', 'Q']
random.shuffle(cards)
print(cards) # 输出类似 ['3', 'A', 'Q', '2', 'K']3.4 特定分布随机数
这些函数在模拟和统计学中非常有用。
random.gauss(mu, sigma)/random.normalvariate(mu, sigma)
- 作用:生成符合高斯(正态)分布的随机浮点数。
mu是均值,sigma是标准差。
random.expovariate(lambd)
- 作用:生成符合指数分布的随机浮点数。
lambd是速率参数(1/均值)。
random.triangular(low, high, mode)
- 作用:生成一个
[low, high]之间的随机浮点数,其众数(峰值)由mode参数指定。
4. 示例与应用场景
场景 1:生成随机验证码
import random
import string
def generate_verification_code(length=6):
"""生成数字和字母组合的验证码"""
# 所有可用的字符:数字+大写字母
all_chars = string.digits + string.ascii_uppercase
# 从 all_chars 中无放回地抽取 length 次(但因为无重复,所以用sample)
# 但验证码通常允许重复,所以应该用 choices
code = ''.join(random.choices(all_chars, k=length))
return code
print(generate_verification_code()) # 输出类似 '7A2G9K'场景 2:随机分配任务
import random
tasks = ['Task_A', 'Task_B', 'Task_C', 'Task_D']
people = ['Alice', 'Bob', 'Charlie']
# 因为人多任务少,随机分配任务,可能有人没任务
random.shuffle(tasks)
assignment = {}
for i, person in enumerate(people):
# 如果任务数比人多,就分配一个,否则分配 None
assignment[person] = tasks[i] if i < len(tasks) else None
print(assignment)
# 输出类似 {'Alice': 'Task_B', 'Bob': 'Task_D', 'Charlie': 'Task_A'}场景 3:模拟投掷骰子
import random
def roll_dice(times=1):
"""模拟投掷 times 次骰子,返回结果列表"""
results = []
for _ in range(times):
results.append(random.randint(1, 6))
return results
print(roll_dice(5)) # 输出类似 [4, 6, 1, 2, 4]5. 安全警告:random 不适用于加密
重要提示:random 模块生成的伪随机数在密码学上是不安全的。
- 原因:生成的随机数序列理论上可以被预测(通过逆向工程算法和种子)。
- 如果需要用于生成密码、密钥、令牌等安全场景,必须使用
secrets模块(Python 3.6+)。
错误示范:
# 不要这样生成密钥!
token = ''.join(random.choices('abcdef0123456789', k=32))
print(token)正确做法:
import secrets
# 使用 secrets 模块
secure_token = secrets.token_hex(16) # 生成 32 个字符的十六进制随机字符串
print(secure_token)总结
函数/方法 | 描述 | 应用场景 |
| 初始化随机数生成器 | 复现随机结果,调试 |
|
| 生成基础随机概率 |
|
| 模拟骰子,随机索引 |
|
| 在指定范围内取随机小数 |
| 从序列中随机选一个元素 | 随机抽奖,石头剪刀布 |
| 从序列中有放回地抽 k 次 | 允许重复的抽样,加权抽样 |
| 从序列中无放回地抽 k 个唯一元素 | 抽取唯一获奖者,随机问卷 |
| 将序列原地打乱 | 洗牌,打乱列表顺序 |
| 生成正态分布随机数 | 模拟自然现象,统计学 |
希望这份详细的解析能帮助你更好地理解和使用 random 模块!
















