如何生成任意数量列表的全量/任意子集/空元素排列组合
生成多列表的子集组合(含空集与全集)
你要的其实是每个输入列表的所有子集(包括空集和全集)之间的笛卡尔积——先给每个列表生成它能取到的所有可能子集,再把这些子集集合做笛卡尔积,得到的每个元组就是符合要求的排列。
实现代码
首先写一个生成单个列表所有子集的工具函数:
import itertools def get_all_subsets(lst): # 生成列表的所有子集(包含空集和全集) subsets = [] # 遍历从0到列表长度的所有可能元素个数 for length in range(0, len(lst) + 1): # 生成对应长度的所有组合,加入结果列表 subsets.extend(itertools.combinations(lst, length)) # 将元组格式的子集转为列表(若不需要可省略此步) return [list(subset) for subset in subsets]
然后是主函数,用来处理任意数量的输入列表:
def generate_subset_combinations(lists): # 为每个输入列表生成所有子集集合 all_subsets_collections = [get_all_subsets(lst) for lst in lists] # 计算各子集集合的笛卡尔积,得到最终组合 return list(itertools.product(*all_subsets_collections))
测试示例
用你给出的列表测试:
l1 = ['red', 'blue', 'green'] l2 = ['big','small','medium'] l3 = ['fast','slow','stopped'] res = generate_subset_combinations([l1,l2,l3]) # 打印部分目标结果 print(res[0]) # 输出:(['red', 'blue', 'green'], ['big', 'small', 'medium'], ['fast', 'slow', 'stopped']) # 找到包含['red','blue']的组合 print(res[len(get_all_subsets(l1)) - 2]) # 输出:(['red', 'blue'], ['big', 'small', 'medium'], ['fast', 'slow', 'stopped']) # 找到([],[],['fast'])这个组合 target_idx = len(get_all_subsets(l1)) * len(get_all_subsets(l2)) + get_all_subsets(l3).index(['fast']) print(res[target_idx]) # 输出:([], [], ['fast'])
说明
get_all_subsets通过itertools.combinations生成所有长度的子集,涵盖了空集(长度0)到全集(长度等于列表本身)的所有可能。itertools.product负责把各个列表的子集做全组合,确保每个排列里每个位置对应原列表的一个子集,完全符合你的需求。
内容的提问来源于stack exchange,提问作者Topher McData
相关产品推荐
相关产品推荐

