python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python random生成随机数

Python中内置模块random实现随机数生成的完整教学

作者:星河耀银海

本文将深入解析Python中random模块的核心用法,从生成随机浮点数、整数到序列洗牌,手把手教你用seed()固定随机性实现可复现数据划分,更有随机验证码、抽奖程序实战案例,并强调用secrets模块实现加密级安全随机数,帮你避开常见坑点

一、开篇:可控的"随机性"

程序中的"随机"实际上是伪随机——由确定性的算法生成的数列,看起来随机,但可复现。Python的random模块基于Mersenne Twister算法,提供了丰富的随机数生成功能。

基本导入和使用:

import random

# random模块的功能分类:
# - 基本随机:random(), uniform(), randint(), randrange()
# - 序列操作:choice(), choices(), sample(), shuffle()
# - 分布函数:gauss(), expovariate() 等
# - 种子管理:seed(), getstate(), setstate()
# - 系统随机:SystemRandom(加密级)

二、基本随机函数

2.1 浮点数和整数随机

import random

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

# uniform(a, b) —— [a, b] 或 [b, a] 的随机浮点数
print(f"uniform(1, 10): {random.uniform(1, 10):.2f}")
print(f"uniform(10, 1): {random.uniform(10, 1):.2f}")  # 同样有效

# randint(a, b) —— [a, b] 的随机整数(包含两端!)
print(f"randint(1, 6): {random.randint(1, 6)}")  # 模拟骰子
print(f"randint(1, 6): {random.randint(1, 6)}")

# 模拟掷骰子
def roll_dice(n=1, sides=6):
    """掷n个sides面的骰子"""
    return [random.randint(1, sides) for _ in range(n)]

print(f"掷2个骰子: {roll_dice(2)}")
print(f"掷3个20面骰子: {roll_dice(3, 20)}")

# randrange(start, stop, step) —— 随机从range中选一个
print(f"randrange(0, 100, 5): {random.randrange(0, 100, 5)}")  # 0,5,10,...,95

2.2 序列随机操作

import random

fruits = ["苹果", "香蕉", "橙子", "葡萄", "西瓜", "芒果"]

# choice(seq) —— 随机选一个元素
print(f"今日推荐水果: {random.choice(fruits)}")

# choices(seq, k=n) —— 有放回随机选n个(可能重复)
print(f"抽3次(有放回): {random.choices(fruits, k=3)}")

# 带权重的随机选择
weights = [0.4, 0.2, 0.15, 0.1, 0.1, 0.05]  # 权重之和为1
result = random.choices(fruits, weights=weights, k=1000)
from collections import Counter
print("权重采样统计:")
for fruit, count in Counter(result).most_common():
    print(f"  {fruit}: {count}次")

# sample(seq, k=n) —— 无放回随机选n个(不重复)
print(f"随机抽3个(无放回): {random.sample(fruits, k=3)}")

# shuffle(seq) —— 原地打乱序列
cards = list(range(1, 53))
random.shuffle(cards)
print(f"洗牌后前5张: {cards[:5]}")

# ⚠️ shuffle是原地操作,返回None!
# shuffled = random.shuffle(cards)  # shuffled是None!

三、分布函数

import random

# gauss(mu, sigma) —— 正态分布(高斯分布)
# mu: 均值,sigma: 标准差
heights = [random.gauss(170, 10) for _ in range(1000)]
avg = sum(heights) / len(heights)
print(f"生成1000人身高:均值={avg:.1f}(预期170)")

# 其他分布
# random.triangular(low, high, mode) —— 三角分布
# random.betavariate(alpha, beta) —— Beta分布
# random.expovariate(lambd) —— 指数分布
# random.gammavariate(alpha, beta) —— Gamma分布

# 💡 这些分布在模拟、统计、机器学习中有特定用途
# 日常开发中最常用的是gauss()和uniform()

四、随机种子和可复现性

4.1 seed()——固定随机性

import random

# seed() —— 设置随机种子
# 相同的种子 → 相同的随机序列

random.seed(42)
print("种子=42:")
print([random.randint(1, 100) for _ in range(5)])
# [82, 15, 4, 95, 36]

random.seed(42)  # 重新设置相同种子
print("种子=42(第二次):")
print([random.randint(1, 100) for _ in range(5)])
# [82, 15, 4, 95, 36]  ← 完全相同!

# 💡 为什么需要可复现的随机?
# 1. 测试——每次测试用同样的"随机"数据
# 2. 调试——重现bug
# 3. 机器学习——对比不同模型的性能(数据划分一致)
# 4. 游戏——用种子生成相同的关卡地图

# 不指定种子——每次运行结果不同
# random.seed()  # 使用系统时间作为种子(默认行为)

# 保存和恢复随机状态
state = random.getstate()  # 保存当前状态
r1 = random.randint(1, 100)

random.setstate(state)  # 恢复到保存的状态
r2 = random.randint(1, 100)
print(f"r1={r1}, r2={r2}, 相同: {r1 == r2}")  # True

4.2 实战:可复现的数据划分

import random

def split_train_test(data, test_ratio=0.2, seed=42):
    """划分训练集和测试集(可复现)"""
    random.seed(seed)
    shuffled = data.copy()
    random.shuffle(shuffled)

    split_point = int(len(data) * (1 - test_ratio))
    train = shuffled[:split_point]
    test = shuffled[split_point:]

    return train, test

data = list(range(100))
train, test = split_train_test(data, seed=42)
print(f"训练集: {len(train)}, 测试集: {len(test)}")

# 再次运行——结果相同
train2, test2 = split_train_test(data, seed=42)
print(f"相同划分: {train == train2 and test == test2}")  # True

五、实战案例

5.1 随机验证码和密码

import random
import string

def generate_code(length=6):
    """生成数字验证码"""
    return ''.join(str(random.randint(0, 9)) for _ in range(length))

def generate_password(length=12, include_special=True):
    """生成随机密码"""
    chars = string.ascii_letters + string.digits
    if include_special:
        chars += "!@#$%^&*"

    # 确保密码至少包含各类字符
    password = [
        random.choice(string.ascii_lowercase),
        random.choice(string.ascii_uppercase),
        random.choice(string.digits),
    ]
    if include_special:
        password.append(random.choice("!@#$%^&*"))

    # 填充到指定长度
    password += [random.choice(chars) for _ in range(length - len(password))]
    random.shuffle(password)
    return ''.join(password)

print(f"验证码: {generate_code(6)}")
print(f"密码: {generate_password(12)}")

5.2 抽奖程序

import random

class Lottery:
    """抽奖系统"""

    def __init__(self, prizes, seed=None):
        self.prizes = prizes  # {"一等奖": 1, "二等奖": 3, ...}
        self.participants = []
        if seed is not None:
            random.seed(seed)

    def add_participant(self, name):
        self.participants.append(name)

    def draw(self):
        """进行抽奖"""
        winners = {}
        remaining = list(self.participants)

        for prize_name, count in self.prizes.items():
            if len(remaining) < count:
                break
            drawn = random.sample(remaining, count)
            winners[prize_name] = drawn
            remaining = [p for p in remaining if p not in drawn]

        return winners

lottery = Lottery({"一等奖": 1, "二等奖": 2, "三等奖": 5}, seed=42)
for i in range(1, 51):
    lottery.add_participant(f"参与者{i}")

results = lottery.draw()
for prize, winners in results.items():
    print(f"{prize}: {', '.join(winners)}")

六、加密级随机数

# ⚠️ random模块不适合安全/加密用途
# 对于密码、token等场景,使用secrets模块!

import secrets

# 生成加密安全的随机token
token = secrets.token_hex(16)
print(f"安全token: {token}")

# 生成URL安全的token
url_token = secrets.token_urlsafe(16)
print(f"URL安全token: {url_token}")

# 安全的随机选择
choices = ["A", "B", "C"]
print(f"安全随机选择: {secrets.choice(choices)}")

# 或者使用 random.SystemRandom —— 它使用操作系统的熵源
sys_random = random.SystemRandom()
print(f"安全随机数: {sys_random.randint(1, 100)}")

七、总结

random模块是日常开发中最常用的模块之一。从生成测试数据到实现随机算法,它无处不在。

核心要点:

  1. 伪随机——可复现,用seed()固定
  2. 基本函数:random(), randint(), choice(), shuffle()
  3. 分布函数:gauss()用于生成正态分布数据
  4. 安全性:random不用于加密,用secrets模块

最常用: randint() (随机整数), choice() (随机选取), shuffle() (洗牌), sample() (抽样), seed() (固定随机)

到此这篇关于Python中内置模块random实现随机数生成的完整教学的文章就介绍到这了,更多相关Python random生成随机数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文