random 模块是 Python 标准库中用于生成伪随机数的核心模块。它提供了多种函数用于生成随机数、进行随机选择、打乱序列等操作。理解其工作原理和正确使用它至关重要。


1. 核心概念:伪随机数

首先要明白,random 模块生成的是伪随机数

  • 真随机数:通过物理现象(如电子元件的噪声、放射性衰变等)产生,完全不可预测。
  • 伪随机数:由一个确定的、可重复的算法(通常是伪随机数生成器,PRNG)根据一个初始值(称为种子,Seed)计算出来的数列。这个数列在统计上看起来是随机的,但只要种子相同,生成的数列就完全相同。

为什么使用伪随机数?
因为计算机是确定性系统,没有真正的随机源。伪随机数具有可重现性,这在程序调试和复现结果时非常有用。


2. 模块的导入

使用前必须先导入模块:

import random

3. 常用函数详解

3.1 初始化与种子 (Seed)

  • random.seed(a=None, version=2)
  • 作用:初始化伪随机数生成器。这是所有随机操作的起点。
  • 参数
  • a:种子值。可以是 intfloatstrbytesbytearray 等。如果 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(如 listtuplestr)中随机返回一个元素。
  • 示例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)

总结

函数/方法

描述

应用场景

seed(a=None)

初始化随机数生成器

复现随机结果,调试

random()

[0.0, 1.0) 的随机浮点数

生成基础随机概率

randint(a, b)

[a, b] 的随机整数

模拟骰子,随机索引

uniform(a, b)

[a, b] 的随机浮点数

在指定范围内取随机小数

choice(seq)

从序列中随机选一个元素

随机抽奖,石头剪刀布

choices(pop, k=1)

从序列中有放回地抽 k 次

允许重复的抽样,加权抽样

sample(pop, k)

从序列中无放回地抽 k 个唯一元素

抽取唯一获奖者,随机问卷

shuffle(x)

将序列原地打乱

洗牌,打乱列表顺序

gauss(mu, sigma)

生成正态分布随机数

模拟自然现象,统计学

希望这份详细的解析能帮助你更好地理解和使用 random 模块!