pin_drop当前位置:知识文库 ❯ 图文

itertools.product详解 - Python笛卡尔积与全组合

一、概述

itertools.product 是 Python 标准库 itertools 模块中的组合迭代器之一,用于计算多个可迭代对象的笛卡尔积。笛卡尔积是集合论中的基本概念,即将每个输入迭代器中的每个元素与其他迭代器中的每个元素进行全组合。product 还支持 repeat 参数,用于将同一个可迭代对象与自身进行多次笛卡尔积。

这在生成测试用例、穷举搜索空间、密码破解、商品 SKU 组合等场景中极为有用。它用一行代码替代了多层嵌套 for 循环,极大地简化了代码。


二、语法

代码示例

itertools.product(*iterables, repeat=1)

三、参数说明

参数 类型 必填 默认值 说明
*iterables 多个可迭代对象 需要计算笛卡尔积的可迭代对象
repeat int 1 将输入的可迭代对象重复参与计算的次数

四、返回值

返回一个迭代器对象,产生输入可迭代对象笛卡尔积中的元组。元组中元素的顺序与输入可迭代对象的顺序一致。结果总数为各输入迭代器元素个数的乘积(含 repeat 时为重复次方的乘积)。


五、代码示例

示例1:基本笛卡尔积

代码示例

import itertools

# 两个列表的笛卡尔积
colors = ['红', '绿']
sizes = ['S', 'M', 'L']
result = list(itertools.product(colors, sizes))
print("颜色x尺码:", result)

# 输出:
# 颜色x尺码: [('红', 'S'), ('红', 'M'), ('红', 'L'), ('绿', 'S'), ('绿', 'M'), ('绿', 'L')]

这个示例模拟了电商场景中颜色与尺码的全组合,2 种颜色 × 3 种尺码 = 6 种 SKU 组合。

示例2:使用 repeat 参数

代码示例

import itertools

# 模拟掷两个骰子的所有组合
dice = range(1, 7)
rolls = list(itertools.product(dice, repeat=2))
print(f"总组合数: {len(rolls)}")
print("前5个组合:", rolls[:5])

# 统计点数之和为7的组合
sum7 = [pair for pair in rolls if sum(pair) == 7]
print(f"和为7的组合: {sum7}, 共{len(sum7)}种")

# 输出:
# 总组合数: 36
# 前5个组合: [(1, 1), (1, 2), (1, 3), (1, 4), (1, 5)]
# 和为7的组合: [(1, 6), (2, 5), (3, 4), (4, 3), (5, 2), (6, 1)], 共6种

repeat=2 将骰子面集合与自身做笛卡尔积,等价于 product(dice, dice)。这在模拟重复实验时非常方便。

示例3:生成密码组合与测试用例

代码示例

import itertools

# 生成简单的密码组合(2位数字+1位字母)
digits = '012'
letters = 'AB'
passwords = list(itertools.product(digits, digits, letters))
print("密码组合:", [''.join(p) for p in passwords])

# 生成测试用例:操作系统 x 浏览器 x 分辨率
os_list = ['Windows', 'macOS']
browser_list = ['Chrome', 'Firefox']
resolution_list = ['1920x1080', '1366x768']
test_cases = list(itertools.product(os_list, browser_list, resolution_list))
print(f"\n测试用例数: {len(test_cases)}")
for tc in test_cases:
    print(f"  {tc[0]} + {tc[1]} + {tc[2]}")

# 输出:
# 密码组合: ['00A', '00B', '01A', '01B', '02A', '02B', '10A', '10B', '11A', '11B', '12A', '12B', '20A', '20B', '21A', '21B', '22A', '22B']
#
# 测试用例数: 8
#   Windows + Chrome + 1920x1080
#   Windows + Chrome + 1366x768
#   Windows + Firefox + 1920x1080
#   Windows + Firefox + 1366x768
#   macOS + Chrome + 1920x1080
#   macOS + Chrome + 1366x768
#   macOS + Firefox + 1920x1080
#   macOS + Firefox + 1366x768

在测试工程中,product 是自动化测试用例生成的利器。多个维度的参数组合只需一行代码即可穷举。


六、实际应用场景

  • 测试用例生成:自动生成多维度组合的测试用例,确保覆盖所有参数组合

  • 密码与序列生成:穷举生成所有可能的密码组合或编码序列

  • 组合优化:在运筹学和算法中,穷举所有可能的参数组合以寻找最优解


七、注意事项

注意1:笛卡尔积的结果数量是指数级增长的。如果有 n 个迭代器,每个有 m 个元素,结果总数为 m^n。对于大型输入,请务必评估内存和时间消耗。

注意2product 在开始计算前会先将所有输入可迭代对象缓存为元组,因此即使输入是迭代器,也会被完全消费。

注意3repeat 参数不是重复输出结果,而是将输入的可迭代对象重复参与笛卡尔积计算。product('AB', repeat=3) 等价于 product('AB', 'AB', 'AB')

提示:当组合数量巨大时,不要用 list() 转换,而是直接遍历迭代器或配合 islice 分批处理。


八、相关方法对比

特性 itertools.product itertools.permutations itertools.combinations 嵌套 for 循环
是否考虑顺序
是否允许重复 是(同元素可多次出现) 取决于实现
输出长度 各输入长度之积 n!/(n-r)! C(n,r) 各输入长度之积
典型用途 笛卡尔积、全组合 排列问题 组合问题 简单嵌套遍历
代码简洁度 极高 极高 极高 低(嵌套层数多)

九、小结

  • product 计算多个可迭代对象的笛卡尔积,结果数量为指数级

  • repeat 参数可将同一迭代器重复参与笛卡尔积

  • 适用于测试用例生成、密码穷举、组合优化等场景

  • 注意结果数量的指数增长,大数据集需谨慎使用


十、练习题

练习1

使用 itertools.product 生成一副扑克牌的所有组合(4种花色 x 13个点数),并统计总数。

练习2

使用 productrepeat=3 生成所有由 'ABC' 三个字母组成的 3 位密码,并筛选出包含至少一个 'A' 的密码。

练习3

某餐厅提供 3 种主食、4 种配菜和 2 种饮品,使用 product 生成所有套餐组合,并输出总数。

常见问题

product 和嵌套 for 循环有什么区别?

两者功能等价,但 product 用一行代码替代了多层嵌套 for 循环,代码更简洁。此外,product 返回惰性迭代器,可以延迟计算,而嵌套 for 循环通常是立即执行。

repeat 参数的实际含义是什么?

repeat 不是重复输出结果,而是将输入的可迭代对象重复参与笛卡尔积计算。product('AB', repeat=3) 等价于 product('AB', 'AB', 'AB'),生成 8 种组合。

product 会缓存输入数据吗?

会。product 在开始计算前会先将所有输入可迭代对象缓存为元组,因此即使输入是迭代器,也会被完全消费。这意味着如果输入是无限迭代器,product 将无法使用。

当组合数量巨大时,应该如何处理?

当组合数量巨大时,不要用 list() 转换,而是直接遍历迭代器或配合 islice 分批处理。这样可以避免内存溢出,并且可以尽早退出处理。

标签: itertools product 笛卡尔积 全组合 测试用例 Python教程 repeat

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: itertools.chain详解 - Python迭代器串联与扁平化 下一篇: itertools.permutations详解 - Python排列与路径规划

poll相关推荐