杰瑞科技汇

python shuffle 函数

shuffle 函数是 Python 标准库 random 模块中的一个重要函数,它的主要作用是对一个序列中的元素进行随机打乱(原地操作)

核心概念

shuffle 函数有两个关键特性需要特别注意:

  1. 原地操作:它会直接修改原始的序列对象,而不是返回一个新的打乱后的序列,这意味着调用 shuffle 后,原始序列的顺序就永久改变了。
  2. 随机性:打乱后的顺序是随机的,每次运行程序,打乱的结果都可能不同(除非设置了随机种子)。

函数签名与参数

shuffle 函数的定义非常简单:

random.shuffle(x)

参数:

  • x:一个可变序列,这是唯一的参数。
    • 必须是可变的:这意味着它不能是字符串、元组 或其他不可变类型,因为 shuffle 需要修改序列中的元素位置。
    • 常见类型:列表 是最常用的 shuffle 参数。

返回值:

  • ,它不返回任何值,如果你尝试将 shuffle 的结果赋给一个变量,这个变量将会是 None

基本用法示例

让我们来看一个最常见和直观的例子:打乱一个列表。

import random
# 1. 定义一个有序的列表
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(f"原始列表: {my_list}")
# 2. 使用 shuffle 打乱列表
random.shuffle(my_list)
# 3. 打印打乱后的列表
# 注意:原始列表 my_list 本身已经被修改了
print(f"打乱后的列表: {my_list}")
# 4. 验证返回值
result = random.shuffle(my_list)
print(f"shuffle 函数的返回值是: {result}") # 输出: None

可能的输出:

原始列表: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
打乱后的列表: [3, 7, 1, 10, 5, 2, 9, 6, 8, 4]
shuffle 函数的返回值是: None

重要注意事项与常见错误

错误示例 1:对不可变序列使用 shuffle

如果你尝试对字符串或元组使用 shuffle,程序会抛出 TypeError

import random
# 错误示例:对字符串使用 shuffle
my_string = "hello"
# random.shuffle(my_string)  # 这会报错: TypeError: 'str' object does not support item assignment
# 错误示例:对元组使用 shuffle
my_tuple = (1, 2, 3)
# random.shuffle(my_tuple)  # 这会报错: TypeError: 'tuple' object does not support item assignment

解决方案:如果你需要打乱一个不可变序列,可以先将它转换为列表,打乱后,如果需要,再转换回原来的类型。

import random
# 打乱字符串
my_string = "python"
# 1. 转换为列表
list_from_string = list(my_string)
print(f"列表形式: {list_from_string}")
# 2. 打乱列表
random.shuffle(list_from_string)
print(f"打乱后的列表: {list_from_string}")
# 3. (可选) 转换回字符串
shuffled_string = "".join(list_from_string)
print(f"打乱后的字符串: {shuffled_string}")

错误示例 2:错误地获取返回值

这是一个非常常见的初学者错误,因为 shuffle 返回 None,所以下面的代码不会达到预期效果。

import random
original_list = [1, 2, 3]
# 错误的做法!
shuffled_list = random.shuffle(original_list)
print(f"shuffled_list 的值: {shuffled_list}") # 输出: None
print(f"original_list 的值: {original_list}") # original_list 被打乱了,但 shuffled_list 是 None

正确的做法:直接对原始列表进行操作,然后使用原始列表。

import random
original_list = [1, 2, 3]
random.shuffle(original_list) # 直接操作 original_list
print(f"打乱后的列表: {original_list}")

shufflesample 的区别

random 模块中还有一个非常相似的函数 sample,它们很容易混淆。

特性 random.shuffle(x) random.sample(population, k)
功能 原地打乱整个序列 从序列中随机抽取 k 个不重复的元素,并返回一个新列表
操作对象 可变序列 (如 list) 任何序列 (可变或不可变,如 list, tuple, str)
是否修改原序列 (返回一个全新的列表)
返回值 None 一个包含 k 个随机元素的新列表
典型用途 洗牌、随机排列顺序 随机抽样、从池中随机选择几个项目

sample 示例:

import random
population = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 从 population 中随机抽取 3 个元素,返回一个新列表
sampled_items = random.sample(population, 3)
print(f"原始序列: {population}")
print(f"随机抽样结果: {sampled_items}")
print(f"原始序列是否改变: {population}") # 原始序列保持不变

可重现性:设置随机种子

在测试、调试或需要确保结果可重现的场景下,我们不希望每次运行程序时顺序都不同,这时可以使用 random.seed() 来设置随机种子。

如果设置了相同的种子,shuffle 的结果在每次程序运行时都会是完全一样的。

import random
# 设置随机种子
random.seed(42) # 42 可以是任何整数
my_list = [1, 2, 3, 4, 5]
random.shuffle(my_list)
print(f"使用种子 42 打乱后的列表: {my_list}")
# 如果再次运行这段代码,seed 仍然是 42,输出结果将完全相同

  • random.shuffle(x) 用于原地打乱一个可变序列(通常是列表)。
  • 没有返回值,直接修改传入的序列。
  • 不能用于字符串、元组等不可变类型。
  • 如果需要从序列中随机抽取一部分元素而不改变原序列,请使用 random.sample()
  • 为了测试和调试,可以使用 random.seed() 来保证随机结果的可重现性。
分享:
扫描分享到社交APP
上一篇
下一篇