一、random模块概述
random 是 Python 标准库中用于生成随机数的模块。它基于梅森旋转算法(Mersenne Twister)实现,可以生成均匀分布的伪随机数。该模块提供了多种随机数生成函数,适用于模拟、游戏、抽样、加密等场景。
import random
print(random.random()) # 0.0 到 1.0 之间的随机浮点数
print(random.randint(1, 10)) # 1 到 10 之间的随机整数
注意:random 生成的是伪随机数(由算法生成,有规律可循)。对于密码学应用,应使用 secrets 模块。
二、基本随机数函数
2.1 生成随机浮点数
| | |
random.random() | | 0.37444887175646646 |
random.uniform(a, b) | | random.uniform(1, 10) |
import random
print(random.random()) # 0.0 <= x < 1.0
print(random.uniform(10, 20)) # 10.0 <= x <= 20.0
2.2 生成随机整数
| | |
random.randint(a, b) | | random.randint(1, 100) |
random.randrange(stop) | | random.randrange(10) |
random.randrange(start, stop) | 返回 [start, stop) 范围内的随机整数 | random.randrange(5, 10) |
random.randrange(start, stop, step) | | random.randrange(0, 100, 5) |
random.getrandbits(k) | | random.getrandbits(8) |
import random
print(random.randint(1, 100)) # 1-100 随机整数
print(random.randrange(10)) # 0-9 随机整数
print(random.randrange(5, 15)) # 5-14 随机整数
print(random.randrange(0, 100, 10)) # 0,10,20,...,90 随机一个
print(random.getrandbits(8)) # 0-255 随机整数
三、序列随机操作
3.1 随机选择
| | |
random.choice(seq) | | random.choice([1,2,3]) |
random.choices(seq, k=1) | | random.choices([1,2,3], k=2) |
random.sample(population, k) | | random.sample([1,2,3,4,5], 3) |
import random
fruits = ['apple', 'banana', 'orange', 'grape', 'watermelon']
# 随机选择一个
print(random.choice(fruits))
# 随机选择多个(可重复)
print(random.choices(fruits, k=3))
# 随机选择多个(不重复)
print(random.sample(fruits, k=3))
# 加权随机选择
weights = [10, 5, 1, 1, 1] # apple 被选中的概率最高
print(random.choices(fruits, weights=weights, k=5))
3.2 随机打乱
import random
cards = list(range(1, 11)) # [1,2,3,4,5,6,7,8,9,10]
print("打乱前:", cards)
random.shuffle(cards)
print("打乱后:", cards)
四、随机分布函数
4.1 均匀分布
| |
random.random() | |
random.uniform(a, b) | |
4.2 其他分布
| |
random.triangular(low, high, mode) | |
random.betavariate(alpha, beta) | |
random.expovariate(lambd) | |
random.gammavariate(alpha, beta) | |
random.gauss(mu, sigma) | |
random.normalvariate(mu, sigma) | |
random.lognormvariate(mu, sigma) | |
random.paretovariate(alpha) | |
random.weibullvariate(alpha, beta) | |
import random
# 正态分布(均值 mu,标准差 sigma)
mu, sigma = 0, 1
print(random.gauss(mu, sigma))
# 指数分布(参数 lambda)
print(random.expovariate(1/5)) # 平均值为5
五、随机种子
使用 random.seed() 可以固定随机数生成器的种子。相同的种子会产生相同的随机数序列,这对于调试和复现实验结果非常重要。
import random
# 设置种子
random.seed(42)
print(random.random()) # 0.6394267984578837
print(random.random()) # 0.025010755222666936
# 再次设置相同的种子,结果相同
random.seed(42)
print(random.random()) # 0.6394267984578837
print(random.random()) # 0.025010755222666936
六、实战案例
6.1 随机密码生成器
import random
import string
defgenerate_password(length=12, use_digits=True, use_punctuation=True):
"""生成随机密码"""
chars = string.ascii_letters # 大小写字母
if use_digits:
chars += string.digits
if use_punctuation:
chars += string.punctuation
password = ''.join(random.choice(chars) for _ inrange(length))
return password
print("密码:", generate_password(16))
print("纯字母密码:", generate_password(10, use_digits=False, use_punctuation=False))
6.2 验证码生成器
import random
import string
defgenerate_captcha(length=6, only_digits=False):
"""生成验证码"""
if only_digits:
chars = string.digits
else:
chars = string.ascii_uppercase + string.digits
# 排除容易混淆的字符
chars = chars.replace('O', '').replace('0', '').replace('I', '').replace('1', '')
return''.join(random.choice(chars) for _ inrange(length))
print("数字验证码:", generate_captcha(6, only_digits=True))
print("混合验证码:", generate_captcha(6))
6.3 抽奖系统
import random
classLottery:
def__init__(self, participants):
self.participants = participants
defdraw_one(self):
"""抽取一人"""
return random.choice(self.participants)
defdraw_multiple(self, n, allow_repeat=False):
"""抽取多人"""
if allow_repeat:
return random.choices(self.participants, k=n)
else:
if n > len(self.participants):
raise ValueError("抽取人数超过总人数")
return random.sample(self.participants, k=n)
defweighted_draw(self, weights):
"""加权抽取"""
return random.choices(self.participants, weights=weights, k=1)[0]
# 使用示例
participants = ["张三", "李四", "王五", "赵六", "小明", "小红"]
lottery = Lottery(participants)
print("一等奖:", lottery.draw_one())
print("二等奖:", lottery.draw_multiple(2))
print("幸运观众:", lottery.weighted_draw([5, 4, 3, 2, 1, 1]))
6.4 洗牌与发牌(扑克牌模拟)
import random
classPokerDeck:
"""扑克牌模拟"""
suits = ['♠', '♥', '♣', '♦']
ranks = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
def__init__(self):
self.cards = [rank + suit for suit inself.suits for rank inself.ranks]
self.deck = self.cards.copy()
defshuffle(self):
"""洗牌"""
random.shuffle(self.deck)
defdeal(self, num):
"""发牌"""
if num > len(self.deck):
raise ValueError("牌不够了")
hand = self.deck[:num]
self.deck = self.deck[num:]
return hand
defreset(self):
"""重置牌堆"""
self.deck = self.cards.copy()
# 使用示例
deck = PokerDeck()
deck.shuffle()
print("玩家手牌:", deck.deal(5))
print("电脑手牌:", deck.deal(5))
print("剩余牌数:", len(deck.deck))
6.5 蒙特卡洛模拟(估算π值)
import random
defestimate_pi(num_points=100000):
"""使用蒙特卡洛方法估算π值"""
inside_circle = 0
for _ inrange(num_points):
x = random.uniform(-1, 1)
y = random.uniform(-1, 1)
if x*x + y*y <= 1:
inside_circle += 1
pi_estimate = 4 * inside_circle / num_points
return pi_estimate
print(f"估算的π值: {estimate_pi()}")
print(f"实际π值: {3.141592653589793}")
6.6 随机数生成游戏(猜数字)
import random
defguess_number():
"""猜数字游戏"""
secret = random.randint(1, 100)
attempts = 0
print("猜数字游戏!我已经想好了1-100之间的一个数字。")
whileTrue:
try:
guess = int(input("请输入你的猜测: "))
attempts += 1
if guess < secret:
print("太小了!")
elif guess > secret:
print("太大了!")
else:
print(f"恭喜!猜对了!用了 {attempts} 次机会。")
break
except ValueError:
print("请输入有效的数字!")
# guess_number()
6.7 随机点名器
import random
import time
defrandom_roll_call(students):
"""随机点名器"""
print("随机点名开始...")
time.sleep(1)
# 滚动效果
for _ inrange(10):
print(f"\r{random.choice(students)}", end='', flush=True)
time.sleep(0.1)
# 最终结果
selected = random.choice(students)
print(f"\n\n被点到的同学是: {selected}!")
students = ["张三", "李四", "王五", "赵六", "小明", "小红", "小刚", "小丽"]
random_roll_call(students)
6.8 随机时间调度
import random
import time
from datetime import datetime, timedelta
defrandom_scheduler(tasks, duration_seconds=60):
"""随机执行任务"""
start_time = datetime.now()
end_time = start_time + timedelta(seconds=duration_seconds)
while datetime.now() < end_time:
task = random.choice(tasks)
interval = random.uniform(1, 5)
print(f"[{datetime.now().strftime('%H:%M:%S')}] 执行: {task}")
time.sleep(interval)
tasks = ["检查数据库", "发送心跳", "处理队列", "更新缓存", "清理日志"]
# random_scheduler(tasks, 10)
七、注意事项
- 1. 随机种子:相同的种子产生相同的随机序列,适用于调试和复现。
- 2. 线程安全:
random 模块不是线程安全的,多线程环境下建议使用各自独立的 Random 实例。rng = random.Random() # 独立随机数生成器
rng.random()
- 3. 密码学安全:
random 不适用于密码学,请使用 secrets 模块。 - 4. 性能:
random 模块性能较好,但大量随机数生成时应考虑向量化方法(如 numpy.random)。 - 5.
random.shuffle 是原地操作:会修改原序列,返回 None。 - 6.
random.sample 与 random.choices: - •
sample:不重复抽取,抽取数量不能超过序列长度。
八、总结
| |
| random(), uniform(), randint(), randrange() |
| choice(), choices(), sample(), shuffle() |
| seed() |
| gauss() |
核心要点:
- • 使用
random.seed() 可复现随机结果。 - •
random.choice() 用于单元素选择,random.sample() 用于不重复选择,random.choices() 用于可重复选择。 - •
random.shuffle() 原地打乱序列。 - • 蒙特卡洛模拟、游戏开发、抽样调查等场景广泛使用随机数。
掌握 random 模块,可以为你的程序增加随机性和不确定性,是游戏开发、模拟仿真、数据采样等领域不可或缺的工具。