应使用 random.choices() 实现加权随机抽样,因其自动归一化权重、支持浮点数和动态权重;random.choice() 仅支持等概率抽取,无法满足权重需求。

直接用 random.choices(),别写轮子,也别手动算累积概率。
为什么不用 random.choice()?
random.choice() 只支持等概率抽取,完全忽略权重。如果你传入 weights=[10, 1, 1],它不会让第一个元素出现概率≈83%,而是三者各占1/3——这和需求完全不符。
常见错误是试图用 random.choice() 配合重复元素(比如把元素A塞10次进列表),但这样会大幅膨胀内存,且无法处理浮点权重或动态权重。
- 权重为浮点数(如
[0.7, 0.25, 0.05])时,重复法失效 - 列表很大、权重差异极大时,构造重复列表可能 OOM
- 权重随运行时变化,每次重建列表开销高
random.choices() 的正确用法
Python 3.6+ 内置,一行解决,自动归一化权重,支持整数/浮点数/任意可迭代权重序列。
基本形式:random.choices(population, weights=weights, k=1)
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
-
population:待抽样的列表(任何可迭代对象都行) -
weights:必须和population等长的数字序列,可以是list、tuple、numpy.ndarray(但注意 numpy 类型需兼容 Python float 转换) -
k:抽多少个,默认 1;设为k=5就返回长度为 5 的列表,允许重复抽取
示例:
import random items = ['apple', 'banana', 'cherry'] weights = [10, 2, 1] picked = random.choices(items, weights=weights, k=1)[0] # 返回单个元素 # 或一次抽多个: samples = random.choices(items, weights=weights, k=3) # 如 ['apple', 'apple', 'banana']
权重为零或负数?会报错
random.choices() 要求所有权重 ≥ 0,且至少有一个 > 0。遇到 0 权重会静默跳过该元素;但只要出现负数,立刻抛出 ValueError: weights sum must be positive。
- 想“禁用”某个元素?显式过滤掉它,别留
0权重 - 权重来自计算(比如相似度得分),记得做
max(0, x)截断再归一化(不过choices不需要你手动归一化) - 空权重列表或全零权重 → 报错,务必提前校验
安全写法示例:
ValueError: The number of weights does not match the population
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










