如何在Python中实现列表的笛卡尔积(非扁平化展开)
问题描述
给定嵌套列表:
my_list = [["a"], ["b"], ["c", "d"], ["e", "f", "g"]]
需要生成所有可能的元素组合,要求每个子列表的元素个数与原列表的子列表数量一致,总个数为各子列表长度的乘积,输出示例如下:
output = [["a","b","c","e"],["a","b","d","e"],["a","b","c","f"],["a","b","d","f"],["a","b","c","g"],["a","b","d","g"]]
原提问者认为无法通过列表推导式实现,寻求解决方法。
解决方案
方法1:用itertools.product快速实现
Python标准库的itertools.product专门用来生成多个可迭代对象的笛卡尔积,完美匹配需求,代码最简洁:
import itertools my_list = [["a"], ["b"], ["c", "d"], ["e", "f", "g"]] output = [list(item) for item in itertools.product(*my_list)] print(output)
这里*my_list把嵌套列表拆成独立的参数传入product,它会生成所有可能的元组组合,再通过列表推导式把每个元组转为列表,就得到目标输出。
方法2:用列表推导式实现(包括通用递归版)
其实完全可以用列表推导式实现,分两种场景:
固定子列表数量的情况
如果原列表的子列表数量固定(比如本题的4个),直接写嵌套推导即可:
my_list = [["a"], ["b"], ["c", "d"], ["e", "f", "g"]] output = [ [x, y, z, w] for x in my_list[0] for y in my_list[1] for z in my_list[2] for w in my_list[3] ] print(output)
任意子列表数量的通用情况
如果原列表的子列表数量不固定,可以用递归式的列表推导式实现通用版本:
def generate_combinations(lists): if not lists: return [[]] return [ [item] + combo for item in lists[0] for combo in generate_combinations(lists[1:]) ] my_list = [["a"], ["b"], ["c", "d"], ["e", "f", "g"]] output = generate_combinations(my_list) print(output)
这个递归函数会逐层拆解原列表,遍历当前层的每个元素,和后续层生成的所有组合拼接,最终得到所有符合要求的组合。
内容的提问来源于stack exchange,提问作者Mike J
相关产品推荐
相关产品推荐

