用 Python 标准库处理随机:random(选择、采样、洗牌、可复现性)
系列 04 – 随机数生成与数据随机化
“随便挑一个”, “打乱顺序”, “不重复地挑几个”, “给不同概率的选项分配权重”。 这些功能在游戏、测试数据生成、简单仿真、数据拆分等场景中经常出现。

Python 标准库中的 random 模块可以用简短代码完成这些需求。
但需要注意的是,random 并不适合安全用途。
1. random 产生的“随机”到底是什么?
random 生成的是伪随机数(PRNG)。它不是完全不可预测的自然随机数,而是基于内部状态生成“看似随机”的数列。
- 同一初始状态(种子)会得到相同的结果。
- 这使得调试和可复现实验变得容易。
- 但在攻击者可以推测状态的安全场景中并不合适(后面会介绍
secrets)。
2. 基础随机数:数值生成
2.1 0 ≤ x < 1 的浮点数:random()
import random
x = random.random()
print(x) # 0.0 <= x < 1.0
2.2 整数范围:randint(a, b) / randrange()
import random
print(random.randint(1, 6)) # 1~6(两端都包含)
print(random.randrange(0, 10, 2)) # 0,2,4,6,8 中的一个
randint(a, b)包含 a 与 b。randrange(start, stop, step)与 range 规则相同(stop 不包含)。
2.3 浮点数范围:uniform(a, b)
import random
print(random.uniform(1.5, 3.5))
3. 在集合中挑选:选择、采样、洗牌
3.1 随机挑一个:choice()
import random
items = ["rock", "paper", "scissors"]
print(random.choice(items))
3.2 随机挑多个(不重复):sample()
import random
nums = list(range(1, 46))
picked = random.sample(nums, k=6) # 不重复地挑 6 个
print(picked)
sample()不修改原始列表。- 结果 不重复。
3.3 列表洗牌:shuffle()(原地修改)
import random
deck = list(range(10))
random.shuffle(deck)
print(deck)
shuffle()直接 原地 修改列表。- 若想保留原始列表,可用
sample()生成一个打乱后的副本。
import random
deck = list(range(10))
shuffled = random.sample(deck, k=len(deck))
print(deck)
print(shuffled)
4. 给不同概率分配权重:choices()
当你想实现“常见、稀有、传奇”之类的选择时非常有用。
import random
items = ["common", "rare", "legendary"]
weights = [85, 14, 1] # 也可以直接使用 0~1 的概率
result = random.choices(items, weights=weights, k=10)
print(result)
choices()默认 允许重复。weights可以是概率(0~1)或比例。
5. 可复现结果:seed()
给定相同的种子,结果会完全一致,尤其在示例或测试中非常实用。
import random
random.seed(42)
print(random.randint(1, 100))
print(random.randint(1, 100))
即使调用了多种函数,只要顺序相同,结果也相同。
提示:
seed()影响全局状态。若不想干扰全局,可单独创建random.Random()实例。
6. 本地随机数生成器:random.Random()
不想改动全局状态时,可以使用本地 RNG。
import random
rng = random.Random(42) # 本地 RNG
print(rng.randint(1, 100))
print(rng.randint(1, 100))
此模式在库代码或多个模块共享随机数时尤为有用。
7. 安全随机数:使用 secrets 而非 random
random 是伪随机,存在可预测性。对于令牌、验证码、密码重置链接等安全用途,推荐使用 secrets。
import secrets
token = secrets.token_urlsafe(16)
print(token)
secrets采用系统安全随机源。
8. 常用模式示例
8.1 从数据中随机挑选 1/多
import random
users = ["u1", "u2", "u3", "u4", "u5"]
print(random.choice(users)) # 1 人
print(random.sample(users, k=2)) # 2 人(不重复)
8.2 随机打乱后取前部
import random
data = list(range(100))
random.shuffle(data)
train = data[:80]
test = data[80:]
8.3 简单的“加权轮盘”
import random
prizes = ["A", "B", "C", "D"]
weights = [1, 3, 10, 86] # D 最常出现
print(random.choices(prizes, weights=weights, k=1)[0])
9. 小结
random 是一个把“随机选择”这一广泛需求浓缩成小 API 的模块。
- 单个挑选:
choice - 不重复挑选:
sample - 列表洗牌:
shuffle - 加权挑选:
choices - 可复现:
seed或random.Random() - 安全随机:
secrets
下一期将继续探讨 statistics、math 等数值处理的标准库。
相关文章: