Python random 模块:随机数生成的 6 个核心方法
引言:用"抽奖箱"理解随机数
生活里到处都有"随机":掷骰子、抽奖、洗牌、生成验证码、给试卷随机出题……程序世界同样需要这些能力。Python 把它们打包进一个标准库模块——random,你不需要安装任何东西,导入即可使用。
先建立一个直观印象:可以把 random 模块想象成一台"会抽签的机器",里面有好几个不同的出口:
- 有的出口专门吐小数(
random()、uniform()); - 有的出口专门吐整数(
randint()); - 有的出口负责从一堆东西里挑一个或几个(
choice()、sample()); - 还有一个出口负责把牌洗乱(
shuffle())。
这一篇,我们就把这 6 个最常用的方法逐个讲透:每个方法的语法、参数、返回值、典型场景,再配上能直接运行的实战案例,最后用一张表帮你"遇到需求时对号入座"。
一、导入模块与随机数种子 seed()
1.1 导入 random 模块
random 是 Python 自带的标准库,无需安装,在代码开头导入即可:
import random # 导入 random 模块,之后用 random.xxx() 调用里面的函数之后所有随机函数都以 random. 作为前缀,例如 random.random()、random.randint(1, 6)。
1.2 种子 seed():让随机数"可复现"
在讲 6 个方法之前,必须先认识一个"幕后主角"——随机数种子。
一个关键真相:计算机其实生成不出真正的随机数。它内部靠一套固定的数学公式来"算"出看似随机的数字。这套公式有一个起点,这个起点就叫种子(seed)。只要种子相同,算出来的随机数序列就完全相同——这就是随机数的"可复现性"。
打个比方:种子就像"一盒磁带"——你按下播放键,听到的歌曲顺序永远一样;换成另一盒磁带,顺序才不同。
- 不设置种子:Python 会用当前系统时间等作为种子,所以每次运行结果通常不同(真·随机体验);
- 手动设置种子:
random.seed(任意整数),之后产生的随机数序列就会被"固定"下来,每次运行结果一致(便于调试、复现实验、写单元测试)。
import random
# 场景一:不设置种子 —— 每次运行结果都不一样
print(random.random()) # 第一次运行可能是 0.5xxx,第二次运行又会变
# 场景二:设置相同的种子 —— 每次运行结果完全一致
random.seed(42) # 把种子固定为 42
print(random.random()) # 输出: 0.6394267984578837(固定值)
print(random.random()) # 输出: 0.025010755222666936(固定值)
random.seed(42) # 重新设回同样的种子,序列会从头再来一遍
print(random.random()) # 输出: 0.6394267984578837(和上面第一个完全相同)记忆口诀:
seed()是"遥控器上的复读键"——设了它,随机就变成"可控的随机"。开发调试时非常有用,测试通过后想恢复真正的随机,把seed()那行删掉即可。
二、random():生成 [0.0, 1.0) 区间的小数
2.1 语法与说明
random.random()- 参数:不需要任何参数;
- 返回值:一个浮点数(小数),范围是 [0.0, 1.0);
- 区间解释:方括号
[表示"包含"(可能等于 0.0),圆括号)表示"不包含"(永远不会等于 1.0)。所以它可能生成 0.0,但绝不会生成 1.0。
2.2 实战案例:模拟"抛硬币概率"与"抽中概率判定"
import random
# 案例 1:生成一个 0 到 1 之间的随机小数
num = random.random()
print(num) # 输出: 例如 0.738274611233(每次运行不同,但都在 [0, 1) 内)
# 案例 2:模拟"30% 中奖概率"——随机数小于 0.3 就算中奖
if random.random() < 0.3:
print("恭喜,中奖啦!") # 约 30% 的概率执行这一行
else:
print("很遗憾,未中奖。") # 约 70% 的概率执行这一行使用场景:
random()是所有随机数的"地基"。当你需要"按某个概率发生某件事"(比如 30% 概率中奖、10% 概率触发彩蛋),就用它来判断。
三、randint():生成指定闭区间的随机整数
3.1 语法与说明
random.randint(a, b)- 参数:
a和b是两个整数,分别表示区间的下限和上限; - 返回值:一个整数,范围是 [a, b](两端都包含,是"闭区间");
- 注意:
a必须小于等于b,否则会报错。
3.2 实战案例:模拟掷骰子与生成验证码
import random
# 案例 1:模拟掷一个六面骰子(结果在 1~6 之间,含 1 和 6)
dice = random.randint(1, 6)
print("骰子点数:", dice) # 输出: 骰子点数: 3(每次运行是 1~6 之间的随机整数)
# 案例 2:生成一个 4 位的随机验证码
code = random.randint(1000, 9999) # 范围 1000~9999,正好是四位数字
print("你的验证码是:", code) # 输出: 你的验证码是: 5823(四位随机整数)使用场景:只要需求是"在一个整数范围内随便取一个整数",就用
randint()。掷骰子、抽座位号、生成数字验证码、随机选第 N 页,都靠它。
四、uniform():生成指定区间的随机小数
4.1 语法与说明
random.uniform(a, b)- 参数:
a和b是两个数字(整数、小数均可),表示区间的两端; - 返回值:一个浮点数,范围是 [a, b](左右都包含);
- 特殊能力:
a和b谁大谁小都可以——uniform(5, 1)和uniform(1, 5)效果一样,会自动帮你调整方向。
4.2 实战案例:随机生成温度与区间颠倒演示
import random
# 案例 1:模拟温度传感器读数(范围 36.0 ~ 37.5 摄氏度)
temp = random.uniform(36.0, 37.5)
print("当前体温:", round(temp, 2)) # 输出: 当前体温: 36.83(36.0~37.5 之间的小数)
# 案例 2:区间上下限颠倒也没关系
a = random.uniform(5, 1) # 写反了顺序,但照样能生成 1~5 之间的小数
print(a) # 输出: 例如 3.274118(一定在 1~5 之间)使用场景:当随机值需要带小数(温度、身高、价格、坐标点),并且区间两端可能来自变量(谁大谁小不确定)时,
uniform()是最省心的选择。
五、choice():从序列中随机选一个元素
5.1 语法与说明
random.choice(seq)- 参数:
seq是一个非空序列(列表、元组、字符串等都算); - 返回值:序列中的一个元素,类型和序列里的元素一致;
- 注意:序列不能为空,否则会报
IndexError。
5.2 实战案例:随机点菜与随机昵称
import random
# 案例 1:从菜单里随机点一道菜
menu = ["红烧肉", "宫保鸡丁", "鱼香肉丝", "麻婆豆腐", "清炒时蔬"]
dish = random.choice(menu)
print("今天就吃:", dish) # 输出: 今天就吃: 宫保鸡丁(每次从菜单里随机挑一道)
# 案例 2:从字符串里随机取一个字符(字符串也是序列)
letter = random.choice("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
print("随机字母:", letter) # 输出: 随机字母: K(26 个大写字母里随机一个)使用场景:需求是"从一堆东西里挑一个",就用
choice()。随机点菜、随机抽一个人回答问题、随机出题、随机选英雄,都是它的拿手好戏。
六、sample():从序列中随机抽取多个不重复元素
6.1 语法与说明
random.sample(seq, k)- 参数:
seq是源序列;k是要抽取的元素个数(必须是不超过序列长度的非负整数); - 返回值:一个新列表,里面装着随机抽出的
k个元素; - 关键特点:抽出来的元素不会重复(相当于"不放回抽样"),且不会修改原序列。
6.2 实战案例:抽奖与随机抽取样本
import random
# 案例 1:从 30 个学号里随机抽 3 个同学回答问题
students = list(range(1, 31)) # 生成学号 1~30 的列表
chosen = random.sample(students, 3) # 随机抽 3 个,且不重复
print("被点到的学号:", chosen) # 输出: 被点到的学号: [7, 23, 15](3 个不重复的学号)
# 案例 2:彩票双色球 —— 从 1~33 里抽 6 个红球
red_balls = random.sample(range(1, 34), 6)
print("红球号码:", red_balls) # 输出: 红球号码: [3, 11, 19, 24, 30, 33](6 个不重复)使用场景:需求是"从一堆东西里挑多个、且不能重复",就用
sample()。抽奖选人、随机抽样调查、双色球开奖、随机抽取若干道题,都离不开它。
七、shuffle():原地打乱列表顺序
7.1 语法与说明
random.shuffle(x)- 参数:
x是一个可变序列,通常是列表; - 返回值:没有返回值(返回
None); - 关键特点:它是"原地"操作——直接修改传入的列表本身,不会生成新列表。
7.2 实战案例:洗牌与打乱题目顺序
import random
# 案例 1:洗一副扑克牌(打乱列表)
cards = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
random.shuffle(cards)
print("洗牌后的顺序:", cards)
# 输出: 洗牌后的顺序: ['8', 'K', '3', 'A', ...](顺序每次运行都不同)
# 案例 2:打乱试卷题目顺序,避免相邻考生作弊
questions = ["第1题", "第2题", "第3题", "第4题", "第5题"]
random.shuffle(questions)
print("出题顺序:", questions)
# 输出: 出题顺序: ['第3题', '第1题', '第5题', '第2题', '第4题']
# 特别提醒:shuffle 的返回值是 None,别写错成 cards = random.shuffle(cards)使用场景:需求是"把现有的列表顺序打乱",就用
shuffle()。洗牌、随机排序题目、随机安排出场顺序,都用它。
八、易混淆方法对比
8.1 random() 与 uniform()
两者都生成"随机小数",但控制范围的能力不同:
| 对比项 | random() | uniform(a, b) |
|---|---|---|
| 参数 | 无 | 需要 a、b 两个参数 |
| 取值范围 | 固定 [0.0, 1.0) | 由你指定 [a, b](可颠倒) |
| 适用场景 | 概率判断、比例、百分比 | 需要指定任意小数区间(温度、价格) |
一句话区分:random() 是"固定 0~1 的概率尺子",uniform() 是"可自定义区间的随机小数生成器"。
import random
print(random.random()) # 永远在 [0, 1) 内
print(random.uniform(10, 20)) # 在 [10, 20] 内,你想定多宽都行8.2 choice() 与 sample()
两者都从序列里"抽元素",但抽的数量和是否重复不同:
| 对比项 | choice(seq) | sample(seq, k) |
|---|---|---|
| 抽取数量 | 固定 1 个 | 由 k 决定(多个) |
| 是否重复 | 只抽一个,无重复概念 | 抽多个时保证不重复 |
| 返回值 | 单个元素(原类型) | 一个新列表 |
| 是否改原 | 不改 | 不改 |
一句话区分:choice() 是"单抽"(抽一个),sample() 是"多抽且不重"(抽一把,像抽奖不把同一个人抽两次)。
import random
names = ["小明", "小红", "小刚"]
print(random.choice(names)) # 只抽 1 个,输出: 小红
print(random.sample(names, 2)) # 抽 2 个且不重复,输出: ['小刚', '小明']补充:如果想让
sample()也"抽出可重复"的元素,可以把序列写两遍,例如random.sample(names * 2, 2);但更推荐直接理解成——需要不重复就用sample,只需一个就用choice。
九、总结:6 种方法的典型使用场景速查表
| 方法 | 一句话作用 | 返回值 | 典型使用场景 |
|---|---|---|---|
random() | 生成 [0, 1) 的小数 | 浮点数 | 概率判断、百分比、抽中率 |
randint(a, b) | 生成 [a, b] 的随机整数 | 整数 | 掷骰子、数字验证码、随机页码 |
uniform(a, b) | 生成 [a, b] 的随机小数(可颠倒) | 浮点数 | 温度、价格、坐标等带小数的随机值 |
choice(seq) | 从序列里抽 1 个元素 | 单个元素 | 随机点菜、抽人回答、随机出题 |
sample(seq, k) | 从序列里抽 k 个不重复元素 | 新列表 | 抽奖、抽样调查、双色球开奖 |
shuffle(x) | 原地打乱列表顺序 | None(原地改) | 洗牌、打乱题目顺序、随机安排出场 |
记忆技巧:
- 要"小数" →
random()或uniform()(一个固定 0~1,一个自定义区间); - 要"整数" →
randint(); - 要"挑元素" → 挑一个用
choice(),挑多个不重复用sample(); - 要"打乱顺序" →
shuffle()(原地改,无返回值)。
核心结论:random 模块的本质是"把各种随机需求封装成不同出口"。先想清楚"我要随机的是什么(小数/整数/元素/顺序)",再去对应表里挑方法,就能十拿九稳。若想调试时让结果固定可复现,记得在代码开头加一句 random.seed(任意整数)。