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

NameSoren AtelierUpdated on 2026/2/10

生成随机数据是编程的基础——从打乱播放列表和抽样调查受访者,到运行蒙特卡洛模拟和创建测试数据集。但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。

📚