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

使用 `itertools.product` 可高效生成任意数量子列表的笛卡尔积,自动适配运行时未知长度的输入,避免递归或嵌套 for 循环,简洁且性能优异。

在 Python 中,当需要从多个列表中各取一个元素组成所有可能的组合(即数学上的笛卡尔积)时,最直接、最 Pythonic 的解法是借助标准库中的 itertools.product。它专为此类场景设计:支持任意数量的可迭代对象,无需预知列表个数(即无需写 n 层嵌套 for 循环),也无需手动实现递归或栈模拟。

✅ 核心用法:解包 + product

假设你有一个动态长度的列表 lists,其中每个元素本身是一个可迭代对象(如 list、str、tuple):

import itertools

# 示例输入:n 个子列表(n 在运行时确定)
lists = [
    ['a', 'b', 'c'],
    ['p', 'q', 'r'],
    ['x', 'y', 'z']
]

# 使用 * 解包,将列表逐个传入 product
result = list(itertools.product(*lists))

print(result)

输出为元组形式的组合:

[('a', 'p', 'x'), ('a', 'p', 'y'), ('a', 'p', 'z'),
 ('a', 'q', 'x'), ('a', 'q', 'y'), ('a', 'q', 'z'),
 ...
 ('c', 'r', 'z')]
? 注意:itertools.product(*lists) 等价于 itertools.product(lists[0], lists[1], ..., lists[n-1]) —— * 是关键,它将列表“展开”为独立参数。

? 转换为列表(如需可变类型)

若要求结果中每个组合是 list(而非 tuple),可简单映射转换:

result_as_lists = [list(combo) for combo in itertools.product(*lists)]
# 或更高效地(避免中间 tuple 构造):
result_as_lists = [list(combo) for combo in itertools.product(*lists)]

示例输出:

[['a', 'p', 'x'], ['a', 'p', 'y'], ['a', 'p', 'z'], ..., ['c', 'r', 'z']]

⚠️ 注意事项

  • 空列表处理:若任一子列表为空,product 返回空迭代器(即 list(...) 为 []),符合笛卡尔积定义(空集参与则结果为空)。
  • 内存考虑:笛卡尔积结果大小为各列表长度乘积(如 [10, 10, 10] → 1000 项;[100, 100, 100] → 100 万项)。对超大规模输入,建议用生成器逐项处理:
    for combo in itertools.product(*lists):
        process(combo)  # 避免一次性加载全部到内存
  • 非列表输入兼容性:product 接受任意可迭代对象。例如 ['ab', 'cd'] 会被视为两个字符串(每个字符可被遍历),等效于 [['a','b'], ['c','d']]。

✅ 总结

itertools.product(*lists) 是解决「动态数量子列表的全组合」问题的标准答案:
✔️ 零配置、零循环、零递归
✔️ 时间复杂度最优(O(∏ len(sublist))),无可避免
✔️ 内存友好(返回迭代器,可按需消费)
✔️ 兼容 Python 3.6+,无需额外依赖

从此告别手写多层嵌套或自定义递归函数——让标准库为你优雅完成笛卡尔积。