pin_drop当前位置:知识文库 ❯ 图文

Python random模块入门 - 伪随机数生成器全面使用指南

概述

random 是 Python 标准库中用于生成伪随机数的模块,其核心算法为 Mersenne Twister(梅森旋转算法,MT19937)。该算法具有极长的周期(2^19937 - 1)和良好的统计特性,是科学计算和模拟仿真中最常用的伪随机数生成器之一。

random 模块提供了丰富的随机数生成功能,涵盖:随机浮点数(random)、随机整数(randintrandrange)、随机选择(choicechoices)、随机采样(sample)、随机洗牌(shuffle)、种子控制(seed)以及多种概率分布(均匀分布、正态分布、指数分布等)。

需要注意的是,random 模块生成的是伪随机数,不适合用于安全敏感的场景(如密码生成、加密密钥等),安全场景应使用 secrets 模块。


导入方式

代码示例

# 方式一:导入整个模块(推荐)
import random

# 使用模块前缀调用
random.randint(1, 10)
random.choice(['a', 'b', 'c'])

# 方式二:导入特定函数
from random import randint, choice, shuffle, sample

# 直接使用函数名调用
randint(1, 10)
choice(['a', 'b', 'c'])

# 方式三:创建独立的随机数生成器
rng = random.Random(42)  # 带种子的独立实例
rng.randint(1, 10)

提示:推荐使用 import random 方式导入,避免命名冲突,且代码可读性更好。

函数分类说明

random 模块主要函数分类如下:

类别 函数 说明
基本随机数 random() [0.0, 1.0) 之间的随机浮点数
随机整数 randint(a, b), randrange() 指定范围内的随机整数
随机浮点数 uniform(a, b) [a, b] 之间的随机浮点数
随机选择 choice(seq), choices() 从序列中随机选择元素
随机采样 sample(population, k) 不重复随机采样
随机洗牌 shuffle(x) 原地打乱序列
种子控制 seed(a) 设置种子、获取/恢复状态
正态分布 gauss(mu, sigma) 正态分布随机数
其他分布 expovariate() 各种概率分布

各函数返回值因函数而异:random() 返回 float 范围 [0.0, 1.0),randint() 返回 intchoice() 返回序列中的单个元素,shuffle() 返回 None(原地修改)。

代码示例

示例1:基本随机数生成

代码示例

import random

# [0.0, 1.0) 之间的随机浮点数
print(f"random(): {random.random():.6f}")

# 指定范围的随机整数 [a, b]
print(f"randint(1, 100): {random.randint(1, 100)}")

# 指定范围的随机浮点数 [a, b]
print(f"uniform(1, 10): {random.uniform(1, 10):.2f}")

# 带步长的随机整数
print(f"randrange(0, 100, 5): {random.randrange(0, 100, 5)}")  # 0-95中5的倍数

# 获取随机比特
print(f"getrandbits(8): {random.getrandbits(8)}")  # 0-255的随机整数

# 输出:
# random(): 0.725419
# randint(1, 100): 42
# uniform(1, 10): 5.73
# randrange(0, 100, 5): 65
# getrandbits(8): 187

示例2:随机选择与采样

代码示例

import random

# 随机选择一个元素
fruits = ['苹果', '香蕉', '橙子', '葡萄', '西瓜']
print(f"随机水果: {random.choice(fruits)}")

# 随机采样(不重复)
sample = random.sample(fruits, 3)
print(f"采样3个: {sample}")

# 带权重的随机选择(可重复)
colors = ['红', '绿', '蓝']
weights = [5, 3, 2]  # 红色概率最高
picked = random.choices(colors, weights=weights, k=10)
print(f"加权选择10次: {picked}")

# 统计权重选择结果
from collections import Counter
counts = Counter(picked)
for color in colors:
    print(f"  {color}: {counts.get(color, 0)}次")

# 输出:
# 随机水果: 橙子
# 采样3个: ['葡萄', '苹果', '西瓜']
# 加权选择10次: ['红', '红', '绿', '红', '蓝', '红', '绿', '红', '红', '绿']
#   红: 6次
#   绿: 3次
#   蓝: 1次

示例3:随机洗牌与模拟

代码示例

import random

# 洗牌
cards = list(range(1, 11))
print(f"洗牌前: {cards}")
random.shuffle(cards)
print(f"洗牌后: {cards}")

# 模拟掷骰子
print(f"\n掷骰子10次: {[random.randint(1, 6) for _ in range(10)]}")

# 模拟抛硬币
coins = [random.choice(['正面', '反面']) for _ in range(10)]
heads = coins.count('正面')
tails = coins.count('反面')
print(f"抛硬币10次: {coins}")
print(f"正面{heads}次, 反面{tails}次")

# 模拟随机漫步
position = 0
steps = 20
path = [position]
for _ in range(steps):
    step = random.choice([-1, 1])
    position += step
    path.append(position)
print(f"\n随机漫步20步: 起点为0, 终点为{position}")
print(f"路径: {path}")

# 输出:
# 洗牌前: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 洗牌后: [7, 3, 1, 9, 5, 2, 10, 4, 8, 6]
#
# 掷骰子10次: [3, 6, 1, 4, 2, 5, 6, 1, 3, 4]
#
# 抛硬币10次: ['正面', '反面', '正面', '正面', '反面', '正面', '反面', '正面', '正面', '反面']
# 正面6次, 反面4次
#
# 随机漫步20步: 起点为0, 终点为4
# 路径: [0, 1, 0, 1, 2, 1, 2, 3, 2, 1, 2, 3, 4, 3, 4, 5, 4, 3, 2, 3, 4]

实际应用场景

  • 模拟仿真:蒙特卡洛模拟、随机过程模拟、随机漫步

  • 游戏开发:随机事件、随机地图、随机掉落、骰子/卡牌

  • 数据采样:从大数据集中随机抽取样本进行分析

  • 随机测试:生成随机测试数据、模糊测试

  • 随机推荐:从候选列表中随机推荐内容

  • 机器学习:数据集划分、随机初始化、随机搜索


注意事项

注意1random 模块生成的是伪随机数,不适合用于安全敏感的场景(如密码生成、加密密钥、安全令牌)。安全场景请使用 secrets 模块。

注意2random 模块的全局函数使用共享的内部状态,在多线程环境中可能产生竞争条件。如需线程安全的随机数生成器,请使用 random.Random() 创建独立实例。

注意3:设置相同的种子(seed)会产生相同的随机数序列,这在测试和复现中很有用,但生产环境通常不应设置固定种子。

注意4random 模块的默认种子基于系统时间/操作系统随机源,每次运行结果不同。

注意5randint(a, b) 是闭区间 [a, b],包含 b。这与 range(a, b) 的左闭右开不同,容易混淆。

提示:需要可复现的随机结果时,在程序开头使用 random.seed(42) 固定种子;需要独立随机流时,使用 random.Random(seed) 创建独立实例。

相关方法对比

特性 random secrets numpy.random os.urandom
安全性 不安全(伪随机) 安全(真随机源) 不安全 安全
性能 极高(向量化)
分布支持 丰富 有限 极丰富
数组支持
线程安全 全局函数不安全 安全 全局函数不安全 安全
典型用途 模拟、采样 密码、令牌 科学计算 加密

小贴士

Mersenne Twister 算法虽然周期极长(2^19937 - 1),但它不是密码学安全的。其内部状态可以通过观察 624 个连续输出值来完全重建,从而预测后续所有随机数。因此在需要安全随机数的场景(如生成密码、API密钥、Session ID)中,务必使用 secrets 模块。

小结

  • random 模块基于 Mersenne Twister 算法生成伪随机数,周期极长,统计特性好

  • 提供随机整数、浮点数、选择、采样、洗牌、分布等丰富功能

  • 不适合安全敏感场景,安全场景使用 secrets 模块

  • 使用 seed() 可以复现随机结果,使用 Random() 创建独立实例

  • randint(a, b) 是闭区间,注意与 range() 的区别


练习题

练习1

使用 random.randint() 模拟掷两个骰子 1000 次,统计点数之和为 7 的次数,并计算概率(理论值约 16.67%)。

练习2

使用 random.choice() 模拟一个简单的猜拳游戏(石头、剪刀、布),人与电脑各出10次,统计胜负。

练习3

使用 random.sample() 从 1 到 100 中随机抽取 5 个不重复的数字,模拟彩票选号。

练习4

使用 random.Random(42) 创建一个独立的随机数生成器,生成 10 个随机整数,然后重新创建相同种子的生成器,验证结果一致。

常见问题

random 模块和 secrets 模块有什么区别?

random 模块基于 Mersenne Twister 算法生成伪随机数,速度快但不安全,适合模拟、游戏、采样等场景。secrets 模块使用操作系统提供的真随机源(如 Windows 的 CryptGenRandom),具有密码学安全性,适合生成密码、令牌、验证码等安全敏感场景。

random.seed() 有什么作用?什么时候应该使用?

random.seed() 用于设置随机数生成器的种子,相同的种子会产生相同的随机数序列。这在需要可复现结果的场景中非常有用:如单元测试、科学实验、机器学习模型训练等。生产环境一般不应设置固定种子,以保证每次运行结果的随机性。

random.choice() 和 random.choices() 有什么区别?

random.choice(seq) 从序列中随机选择一个元素,返回单个值。random.choices(seq, weights, k) 可以带权重进行 k 次随机选择(可重复),返回列表。choices() 还支持 weights 参数指定每个元素的选中概率,适合加权随机选择场景。

random.sample() 和 random.choices() 有什么区别?

random.sample() 是不重复抽样(不放回),适合从总体中抽取不重复的样本,如抽奖、彩票选号。random.choices() 是可重复抽样(有放回),同一个元素可能被多次选中,还支持权重参数。两者的核心区别在于是否允许重复。

random.shuffle() 为什么不返回新列表而是原地修改?

random.shuffle() 原地修改列表是为了节省内存,避免创建新列表的开销。这是 Python 中常见的原地操作模式(如 list.sort()、list.reverse())。如果需要保留原列表,可以在洗牌前先复制:shuffled = original[:],然后 random.shuffle(shuffled)。

标签: Python random模块 随机数 伪随机数 Mersenne Twister 随机采样

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: Python math常量详解 - math.pi、math.e、math.inf、math.nan使用指南 下一篇: Python random.random详解 - 均匀分布随机浮点数与蒙特卡洛实战

poll相关推荐