生成所有嵌套列表的笛卡尔积组合(无需硬编码多层循环)

使用 python 的 `itertools.product` 可高效生成任意数量子列表的笛卡尔积,避免动态嵌套循环难题,适用于运行时才确定列表层数的场景。

在处理动态深度的嵌套列表(例如 [[a,b,c], [p,q,r], ..., [x,y,z]])并需要枚举“从每个子列表中各取一个元素”的所有可能组合时,本质是在计算多个集合的笛卡尔积。手动编写 n 层 for 循环不仅冗长、易错,更因 n 在运行时未知而不可行。

此时,标准库中的 itertools.product 是最简洁、高效且地道的解决方案。它专为这类任务设计:接受多个可迭代对象(或通过解包 *lists 传入一个列表),返回所有有序组合的迭代器。

✅ 基本用法示例

import itertools

# 示例输入:3 个字符串(等价于字符列表)
data = ["abc", "jkl", "xyz"]

# 生成笛卡尔积:等价于 for a in "abc": for j in "jkl": for x in "xyz": ...
result = list(itertools.product(*data))

print(f"共 {len(result)} 种组合")
print("前 5 个结果:", result[:5])

输出:

共 27 种组合
前 5 个结果: [('a', 'j', 'x'), ('a', 'j', 'y'), ('a', 'j', 'z'), ('a', 'k', 'x'), ('a', 'k', 'y')]
? 注意:itertools.product(*data) 中的 * 是关键——它将 data 列表“解包”为独立参数,如 product("abc", "jkl", "xyz"),从而适配函数签名。

✅ 处理真正意义上的列表-of-列表(含非字符串元素)

data = [
    [1, 2],
    ['x', 'y'],
    [True, False]
]

combinations = list(itertools.product(*data))
for combo in combinations:
    print(list(combo))  # 转为 list 便于阅读(product 返回 tuple)

输出:

[1, 'x', True]
[1, 'x', False]
[1, 'y', True]
[1, 'y', False]
[2, 'x', True]
[2, 'x', False]
[2, 'y', True]
[2, 'y', False]

⚠️ 注意事项与最佳实践

  • 内存友好性:itertools.product 返回迭代器,不立即生*部结果。对大规模数据,请直接迭代而非 list() 全部加载,避免内存溢出:
    for combo in itertools.product(*huge_lists):
        process(combo)  # 流式处理
  • 结果类型:默认返回 tuple。若需 list,可用 map(list, product(...)) 或列表推导式:
    result_as_lists = [list(t) for t in itertools.product(*data)]
  • 空输入处理:若任一子列表为空,product 返回空迭代器(即 []),符合数学定义。
  • 性能优势:底层由 C 实现,远快于纯 Python 递归或 functools.reduce 等替代方案。

✅ 总结

当面对“n 个列表,每组取一个元素组成新序列”的通用组合问题时,itertools.product(*lists) 是 Python 生态中最推荐、最鲁棒的解法。它抽象了循环嵌套逻辑,代码简洁、语义清晰、性能优异,且天然支持任意长度的输入列表——完美解决运行时动态维度的挑战。