# 用 Python 标准库处理随机:`random`(选择、采样、洗牌、可复现性) > **系列 04 – 随机数生成与数据随机化** “随便挑一个”, “打乱顺序”, “不重复地挑几个”, “给不同概率的选项分配权重”。 这些功能在游戏、测试数据生成、简单仿真、数据拆分等场景中经常出现。 ![魔法师的赌场把戏](/media/editor_temp/6/d231fe37-ba66-4222-bca7-4d3dd8e33399.png) Python 标准库中的 `random` 模块可以用简短代码完成这些需求。 但需要注意的是,`random` 并不适合安全用途。 --- ## 1. `random` 产生的“随机”到底是什么? {#sec-455748bb14be} `random` 生成的是**伪随机数(PRNG)**。它不是完全不可预测的真随机数,而是基于内部状态生成“看似随机”的数列。 * 同一初始状态(种子)会得到相同的结果。 * 这使得调试和实验复现变得容易。 * 但在攻击者可以推断其内部状态的安全场景中并不合适(后面会介绍 `secrets`)。 --- ## 2. 基础随机数:数值生成 {#sec-d5b02eb13283} ### 2.1 0 ≤ x < 1 的浮点数:`random()` {#sec-0219f1479073} ```python import random x = random.random() print(x) # 0.0 <= x < 1.0 ``` ### 2.2 整数范围:`randint(a, b)` / `randrange()` {#sec-db1bdddd505e} ```python 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)` {#sec-b2ac63ac3cef} ```python import random print(random.uniform(1.5, 3.5)) ``` --- ## 3. 在集合中挑选:选择、采样、洗牌 {#sec-8b4cde32f256} ### 3.1 随机挑一个:`choice()` {#sec-deb7c9f088ca} ```python import random items = ["rock", "paper", "scissors"] print(random.choice(items)) ``` ### 3.2 随机挑多个(不重复):`sample()` {#sec-3f22607831e5} ```python import random nums = list(range(1, 46)) picked = random.sample(nums, k=6) # 不重复地挑 6 个 print(picked) ``` * `sample()` **不修改原始列表**。 * 结果 **不重复**。 ### 3.3 列表洗牌:`shuffle()`(原地修改) {#sec-ccdf58c09400} ```python import random deck = list(range(10)) random.shuffle(deck) print(deck) ``` * `shuffle()` 直接 **原地** 修改列表。 * 若想保留原始列表,可用 `sample()` 生成一个打乱后的副本。 ```python import random deck = list(range(10)) shuffled = random.sample(deck, k=len(deck)) print(deck) print(shuffled) ``` --- ## 4. 根据不同权重进行概率选择:`choices()` {#sec-aa8997456e04} 当你想实现“常见、稀有、传奇”之类的选择时非常有用。 ```python 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()` {#sec-bc5ab726676b} 给定相同的种子,结果会完全一致,尤其在示例或测试中非常实用。 ```python import random random.seed(42) print(random.randint(1, 100)) print(random.randint(1, 100)) ``` 即使调用了多种函数,只要其调用顺序保持一致,结果也会相同。 > 提示:`seed()` 影响全局状态。若不想干扰全局,可单独创建 `random.Random()` 实例。 --- ## 6. 本地随机数生成器:`random.Random()` {#sec-1834e1c42abe} 不想改动全局状态时,可以使用本地 RNG。 ```python import random rng = random.Random(42) # 本地 RNG print(rng.randint(1, 100)) print(rng.randint(1, 100)) ``` 此模式在库代码或多个模块共享随机数时尤为有用。 --- ## 7. 安全随机数:使用 `secrets` 而非 `random` {#sec-362a8ba26346} `random` 是伪随机,存在可预测性。对于令牌、验证码、密码重置链接等安全用途,推荐使用 `secrets`。 ```python import secrets token = secrets.token_urlsafe(16) print(token) ``` * `secrets` 采用系统安全随机源。 --- ## 8. 常用模式示例 {#sec-5f6bd9bdf408} ### 8.1 从数据中随机挑选一个或多个元素 {#sec-366d7b6c1b6f} ```python import random users = ["u1", "u2", "u3", "u4", "u5"] print(random.choice(users)) # 1 人 print(random.sample(users, k=2)) # 2 人(不重复) ``` ### 8.2 随机打乱后获取前部元素 {#sec-8d04aefaf202} ```python import random data = list(range(100)) random.shuffle(data) train = data[:80] test = data[80:] ``` ### 8.3 简单的“加权轮盘” {#sec-d3ba1df51400} ```python import random prizes = ["A", "B", "C", "D"] weights = [1, 3, 10, 86] # D 最常出现 print(random.choices(prizes, weights=weights, k=1)[0]) ``` --- ## 9. 小结 {#sec-ecbe78d7ffd8} `random` 是一个通过简洁的 API 满足“随机选择”这一广泛需求的模块。 * 单个挑选:`choice` * 不重复挑选:`sample` * 列表洗牌:`shuffle` * 加权挑选:`choices` * 可复现:`seed` 或 `random.Random()` * 安全随机:`secrets` 下一期将继续探讨 `statistics`、`math` 等数值处理的标准库。 --- **相关文章:** - [[Python 标准库 - 0] 什么是 Python 标准库?面向初学者的指南](/ko/whitedec/2026/1/29/python-standard-library/) - [[Python 标准库 -1] 文件系统 & OS 环境掌握:pathlib vs os](/ko/whitedec/2026/1/29/file-system-os-environment-master-pathlib-vs-os/) - [[Python 标准库 - 2] 数据存储 & 序列化:json, pickle, csv](/ko/whitedec/2026/1/30/python-json-pickle-csv/) - [[Python 标准库 - 3] 用 Python 处理时间:datetime](/ko/whitedec/2026/1/30/python-datetime-complete-guide/)