1. 引言:为什么需要随机数?
在编程中,随机数扮演着至关重要的角色。无论是模拟现实世界的不确定性(如游戏中的骰子、抽卡),还是用于算法测试(如生成随机数据集)、密码学、机器学习(如权重初始化、数据打乱),甚至是简单的验证码生成,都离不开随机数的支持。
Python 内置的 random 模块为我们提供了生成伪随机数的全套工具。它易于使用,功能强大,是 Python 开发者工具箱中的必备模块。本文将带你从基础到进阶,全面掌握 random 模块的使用。
2. 基础入门:生成简单的随机数
让我们从最基础的几个函数开始,快速上手。
2.1 生成随机浮点数
random.random() 是模块中最基础的函数,它返回一个范围在 [0.0, 1.0) 的随机浮点数(包括 0.0,但不包括 1.0)。
import random
# 生成一个 [0.0, 1.0) 之间的随机浮点数
num = random.random()
print(f"随机浮点数: {num}") # 例如:0.37444887175646646
2.2 生成指定范围的随机整数
random.randint(a, b) 用于生成一个范围在 [a, b] 的随机整数(包括两端)。
# 模拟掷一个六面骰子
dice_roll = random.randint(1, 6)
print(f"骰子点数: {dice_roll}") # 例如:4
# 生成一个1到100之间的随机整数
random_number = random.randint(1, 100)
print(f"1到100的随机数: {random_number}")
random.randrange(start, stop[, step]) 则更加灵活,类似于 range() 函数,可以指定步长,且默认不包括 stop 值。
# 生成一个0到9之间的随机整数
num1 = random.randrange(10)
print(num1) # 例如:7
# 生成一个10到99之间的随机整数(两位随机数)
num2 = random.randrange(10, 100)
print(num2) # 例如:42
# 生成一个0到100之间的随机偶数
even_num = random.randrange(0, 101, 2)
print(f"随机偶数: {even_num}") # 例如:56
2.3 生成指定范围的随机浮点数
random.uniform(a, b) 返回一个范围在 [a, b](或 [b, a])的随机浮点数。
# 生成一个10.0到20.0之间的随机浮点数
float_num = random.uniform(10.0, 20.0)
print(f"10到20的随机浮点数: {float_num:.2f}") # 例如:15.73
3. 序列操作:随机选择与打乱
random 模块提供了强大的工具来处理列表、元组等序列。
3.1 随机选择一个元素
random.choice(seq) 从非空序列 seq 中随机返回一个元素。
fruits = ['apple', 'banana', 'orange', 'grape', 'mango']
selected_fruit = random.choice(fruits)
print(f"今天的水果是: {selected_fruit}") # 例如:orange
# 也可以用于字符串(字符串也是序列)
letter = random.choice('ABCDEFG')
print(f"随机字母: {letter}") # 例如:D
3.2 随机选择多个不重复元素
random.sample(population, k) 从序列或集合 population 中,随机选择 k 个唯一的元素,返回一个新列表。这常用于抽奖、随机抽样等场景。
participants = ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank']
winners = random.sample(participants, 3) # 抽取3名不重复的获奖者
print(f"获奖者是: {winners}") # 例如:['Charlie', 'Alice', 'Frank']
3.3 随机选择多个元素(允许重复)
random.choices(population, weights=None, *, cum_weights=None, k=1) 从 population 中随机选择 k 个元素,允许重复。它还可以通过 weights 参数指定每个元素的权重,实现加权随机。
# 简单随机选择(允许重复)
coin_flips = random.choices(['Heads', 'Tails'], k=5)
print(f"5次抛硬币: {coin_flips}") # 例如:['Heads', 'Tails', 'Heads', 'Heads', 'Tails']
# 加权随机选择:抽奖,一等奖概率10%,二等奖30%,三等奖60%
prizes = ['一等奖', '二等奖', '三等奖']
weights = [0.1, 0.3, 0.6]
result = random.choices(prizes, weights=weights, k=10) # 模拟抽10次
print(f"加权抽奖结果: {result}")
3.4 随机打乱序列顺序
random.shuffle(x) 将序列 x 的元素顺序随机打乱,直接修改原序列。常用于洗牌、随机排列题目等。
cards = ['A♠', 'K♠', 'Q♠', 'J♠', '10♠', '9♠']
print(f"洗牌前: {cards}")
random.shuffle(cards)
print(f"洗牌后: {cards}") # 顺序已被随机打乱
如果想得到一个打乱顺序的新列表而不改变原列表,可以结合 sample 函数:
original_list = [1, 2, 3, 4, 5]
shuffled_list = random.sample(original_list, len(original_list))
print(f"原列表: {original_list}")
print(f"新打乱列表: {shuffled_list}")
4. 高级应用与随机种子
4.1 生成符合特定分布的随机数
除了均匀分布,random 模块还支持其他概率分布。
- 正态分布(高斯分布):
random.gauss(mu, sigma)或random.normalvariate(mu, sigma),其中mu是均值,sigma是标准差。# 生成均值为100,标准差为15的正态分布随机数(模拟智商分数) iq_score = random.gauss(100, 15) print(f"模拟智商分数: {iq_score:.1f}") - 其他分布:模块还提供了
expovariate(指数分布)、betavariate(贝塔分布)等函数,满足更专业的统计模拟需求。
4.2 控制随机性:随机种子
计算机生成的随机数实际上是“伪随机数”,由一个确定的算法根据一个初始值(种子)计算出来。设置相同的种子,就能得到完全相同的随机数序列。这在需要复现结果的场景下非常有用,例如科学实验、机器学习模型调试、游戏关卡生成等。
# 设置随机种子
random.seed(42)
# 第一次运行
print("种子为42时的序列:")
for _ in range(3):
print(random.randint(1, 10), end=' ') # 输出:1 2 10
print("\n---")
# 重置相同的种子
random.seed(42)
print("重置相同种子后的序列:")
for _ in range(3):
print(random.randint(1, 10), end=' ') # 输出:1 2 10 (与上面完全相同)
如果不设置种子,Python 通常会使用系统时间作为默认种子,从而产生看似不可预测的序列。
5. 实战案例
案例1:生成随机验证码
import random
import string
def generate_captcha(length=6):
"""生成指定长度的数字字母混合验证码"""
# 定义字符池:数字 + 大写字母 + 小写字母
characters = string.digits + string.ascii_uppercase + string.ascii_lowercase
# 从字符池中随机选择 length 个字符
captcha = ''.join(random.choices(characters, k=length))
return captcha
print(f"6位验证码: {generate_captcha()}") # 例如:aB3x9K
print(f"4位数字验证码: {''.join(random.choices(string.digits, k=4))}") # 例如:3847
案例2:随机分配任务
def assign_tasks(employees, tasks):
"""将任务随机分配给员工,每人至少一项"""
if len(tasks) < len(employees):
raise ValueError("任务数量不能少于员工数量")
# 先给每个员工随机分配一项任务
assignment = {emp: [] for emp in employees}
remaining_tasks = tasks.copy()
random.shuffle(remaining_tasks)
for i, emp in enumerate(employees):
assignment[emp].append(remaining_tasks[i])
# 将剩余任务随机分配给任意员工
for task in remaining_tasks[len(employees):]:
lucky_emp = random.choice(employees)
assignment[lucky_emp].append(task)
return assignment
employees = ['张三', '李四', '王五']
tasks = ['任务A', '任务B', '任务C', '任务D', '任务E']
result = assign_tasks(employees, tasks)
for emp, assigned_tasks in result.items():
print(f"{emp}: {assigned_tasks}")
6. 安全警告:不要用于密码学
重要提醒:random 模块生成的随机数不适合用于密码学、安全令牌或密钥生成,因为它是可预测的伪随机数。
对于安全敏感的场景,请使用 secrets 模块(Python 3.6+),它专门用于生成密码学安全的随机数。
import secrets
# 生成安全的随机令牌
secure_token = secrets.token_hex(16) # 生成32个字符的十六进制字符串
print(f"安全令牌: {secure_token}")
# 生成安全的随机整数
secure_int = secrets.randbelow(100) # [0, 100)
print(f"安全随机数: {secure_int}")
7. 总结
Python 的 random 模块是一个功能全面且易于使用的伪随机数生成器。通过本文,你应已掌握:
- 基础生成:
random(),randint(),uniform()。 - 序列操作:
choice(),sample(),choices(),shuffle()。 - 高级控制:随机种子
seed()和特定分布函数。 - 安全须知:了解其局限性,在需要安全随机数时使用
secrets模块。
记住,随机性让程序世界变得更加生动和真实。现在,就尝试在你的下一个项目中运用 random 模块吧!

228

被折叠的 条评论
为什么被折叠?



