Skip to content

Python Random:生成随机数、选择和样本

Updated on

生成随机数据是编程的基础——从打乱播放列表和抽样调查受访者,到运行蒙特卡洛模拟和创建测试数据集。但Python的random模块有数十个函数,很容易用错。在需要整数时调用random.random(),在需要多个唯一项时使用choice(),或者忘记random不是加密安全的,都可能导致微妙的bug或安全漏洞。

Python的random模块提供了伪随机数生成的综合工具包。本指南涵盖了你常用的每个函数,并附有清晰的示例说明何时使用每个函数。

📚

随机整数

randint(a, b)

返回一个随机整数N,满足a <= N <= b(包含两个端点)。

import random
 
# Random integer between 1 and 10 (inclusive)
print(random.randint(1, 10))  # e.g., 7
 
# Simulate a dice roll
dice = random.randint(1, 6)
print(f"You rolled a {dice}")
 
# Generate random ages for test data
ages = [random.randint(18, 65) for _ in range(5)]
print(ages)  # e.g., [34, 52, 21, 45, 28]

randrange(start, stop, step)

类似range()但返回一个随机元素。stop值不包含在内。

import random
 
# Random even number between 0 and 100
print(random.randrange(0, 101, 2))  # e.g., 42
 
# Random number from 0 to 9
print(random.randrange(10))  # e.g., 7
 
# Random multiple of 5 from 0 to 100
print(random.randrange(0, 101, 5))  # e.g., 35

随机浮点数

random()

返回[0.0, 1.0)范围内的随机浮点数。

import random
 
print(random.random())  # e.g., 0.7234...
 
# Scale to any range: random float between 10 and 20
value = 10 + random.random() * 10
print(value)  # e.g., 15.23...

uniform(a, b)

返回一个随机浮点数N,满足a <= N <= b

import random
 
# Random temperature between 98.0 and 99.5
temp = random.uniform(98.0, 99.5)
print(f"Temperature: {temp:.1f}F")  # e.g., Temperature: 98.7F
 
# Random price between 9.99 and 29.99
price = round(random.uniform(9.99, 29.99), 2)
print(f"Price: ${price}")

gauss(mu, sigma) -- 正态分布

import random
 
# Generate normally distributed values (mean=100, std=15)
iq_scores = [round(random.gauss(100, 15)) for _ in range(10)]
print(iq_scores)  # e.g., [112, 95, 103, 88, 107, ...]

随机选择

choice(seq)

从非空序列中返回一个随机元素。

import random
 
colors = ['red', 'blue', 'green', 'yellow', 'purple']
print(random.choice(colors))  # e.g., 'green'
 
# Random character from a string
print(random.choice('abcdefghij'))  # e.g., 'f'

choices(population, weights, k)

返回有放回抽取(可能有重复)的k个元素列表。支持权重。

import random
 
# Pick 5 random colors (duplicates allowed)
colors = ['red', 'blue', 'green']
print(random.choices(colors, k=5))  # e.g., ['blue', 'red', 'blue', 'green', 'red']
 
# Weighted selection (red is 5x more likely)
weighted = random.choices(
    ['red', 'blue', 'green'],
    weights=[5, 1, 1],
    k=10
)
print(weighted)  # Mostly 'red'

sample(population, k)

返回无放回抽取(无重复)的k个唯一元素。

import random
 
# Lottery numbers: 6 unique numbers from 1-49
lottery = random.sample(range(1, 50), 6)
print(sorted(lottery))  # e.g., [3, 12, 27, 33, 41, 48]
 
# Random survey sample
employees = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve', 'Frank']
survey_group = random.sample(employees, 3)
print(survey_group)  # e.g., ['Diana', 'Alice', 'Frank']

choice vs choices vs sample

函数放回返回值用途
choice(seq)N/A(单个项)一个元素随机选择一个项
choices(pop, k=n)有放回n个元素的列表加权随机、模拟
sample(pop, k=n)无放回n个唯一元素的列表抽奖、随机子集

洗牌

shuffle(seq)

就地洗牌列表。返回None

import random
 
deck = list(range(1, 53))  # 52 cards
random.shuffle(deck)
print(deck[:5])  # e.g., [37, 12, 48, 3, 21]
 
# Deal 5 cards
hand = deck[:5]
remaining = deck[5:]

种子和可重现性

设置种子使随机输出可重现——对测试和调试至关重要。

import random
 
random.seed(42)
print(random.randint(1, 100))  # Always 81
print(random.random())          # Always 0.0744...
 
# Reset seed for same sequence
random.seed(42)
print(random.randint(1, 100))  # 81 again
print(random.random())          # 0.0744... again

何时使用种子

场景使用种子?原因
单元测试可重现的测试结果
调试重现确切的bug
模拟(分析)可重现的实验
游戏(游戏玩法)玩家期望真正的随机性
安全/加密否(使用secrets种子使输出可预测

生成测试数据

import random
import string
 
def random_string(length=10):
    """Generate a random alphanumeric string."""
    chars = string.ascii_letters + string.digits
    return ''.join(random.choices(chars, k=length))
 
def random_email():
    """Generate a random email address."""
    name = random_string(8).lower()
    domains = ['gmail.com', 'yahoo.com', 'outlook.com']
    return f"{name}@{random.choice(domains)}"
 
def random_user():
    """Generate a random user record."""
    first_names = ['Alice', 'Bob', 'Charlie', 'Diana', 'Eve']
    last_names = ['Smith', 'Jones', 'Brown', 'Wilson', 'Taylor']
    return {
        'name': f"{random.choice(first_names)} {random.choice(last_names)}",
        'email': random_email(),
        'age': random.randint(18, 65),
        'score': round(random.uniform(0, 100), 1),
    }
 
# Generate 5 test users
users = [random_user() for _ in range(5)]
for user in users:
    print(user)

Random与数据科学

对于数据分析工作流,random模块有助于抽样、自助法和创建合成数据集。与pandas结合,你可以快速生成测试DataFrame:

import random
import pandas as pd
 
random.seed(42)
n = 1000
 
df = pd.DataFrame({
    'age': [random.randint(18, 80) for _ in range(n)],
    'income': [round(random.gauss(50000, 15000), 2) for _ in range(n)],
    'category': random.choices(['A', 'B', 'C'], weights=[5, 3, 2], k=n),
})
print(df.describe())

对于随机数据集的交互式探索,PyGWalker (opens in a new tab)可以将任何pandas DataFrame在Jupyter中转换为Tableau风格的可视化UI:

import pygwalker as pyg
walker = pyg.walk(df)

安全警告:random vs secrets

random模块不适合安全用途。如果种子已知,其输出是确定性的和可预测的。对于密码、令牌和加密应用,请使用secrets模块:

import secrets
 
# Cryptographically secure random token
token = secrets.token_hex(16)
print(token)  # e.g., 'a3f2b8c9d1e4f5a6b7c8d9e0f1a2b3c4'
 
# Secure random integer
secure_int = secrets.randbelow(100)
 
# Secure random choice
secure_choice = secrets.choice(['option1', 'option2', 'option3'])
特性randomsecrets
算法梅森旋转(PRNG)操作系统熵源(CSPRNG)
确定性是(有种子时)
速度较慢
用途模拟、游戏、测试密码、令牌、加密
可重现是(使用seed()

FAQ

如何在Python中生成随机整数?

使用random.randint(a, b)获取a和b之间(包含两端)的随机整数。例如,random.randint(1, 10)返回1到10之间的数字。对于不包含上限的范围,使用random.randrange(start, stop)

random.choice和random.sample有什么区别?

random.choice(seq)返回一个随机元素。random.sample(population, k)返回无放回的k个唯一元素。要选择允许重复的多个项目,使用random.choices(population, k=n)

如何使随机结果可重现?

在生成随机数之前调用random.seed(value)。使用相同的种子每次都会产生相同的随机值序列。这对单元测试和调试至关重要。

Python的random模块安全吗?

不安全。random模块使用梅森旋转算法,它是确定性的和可预测的。对于密码或令牌等安全敏感的应用,请改用secrets模块,它使用加密安全的随机源。

如何在Python中随机打乱列表?

使用random.shuffle(my_list)就地打乱列表。它修改原始列表并返回None。如果需要保持原始列表不变,先创建副本:shuffled = my_list.copy(); random.shuffle(shuffled)

总结

Python的random模块涵盖了每种常见的随机化需求:整数用randint,浮点数用uniform,从序列中选择用choice/choices/sample,重新排序用shuffle,可重现性用seed。记住关键区别:choices允许重复(有放回),sample不允许(无放回)。并且永远不要将random用于安全——请改用secrets

📚