Python如何生成列表所有元素的可能组合
问题原因与正确实现方法
问题原因
你需要获取的是列表的幂集,即所有不考虑元素顺序、长度从0(空集)到原列表全长的元素组合。你之前的代码存在两个问题:
- 使用了
permutations排列函数:该函数生成的结果区分元素顺序,例如(1,2)和(2,1)会被判定为两个不同结果,不符合组合的去重要求 - 传入了固定长度参数2:仅会生成长度为2的结果,完全遗漏空集、单元素、三元素的组合。
实现方法
方法1:使用标准库itertools.combinations(推荐)
combinations是专门用于生成不考虑顺序的组合的工具,只要遍历所有可能的组合长度,汇总结果即可:
from itertools import combinations input_list = [1, 2, 3] output = [] # 组合长度范围:0(空集)到列表全长,range左闭右开所以要取len+1 for combo_length in range(len(input_list) + 1): # 生成长度为combo_length的所有组合,转成列表后追加到结果集 output.extend([list(combo) for combo in combinations(input_list, combo_length)]) print(output)
运行输出:
[[], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]]
和预期结果完全一致。
方法2:位运算原生实现(无需导入依赖)
长度为n的列表,总共有2^n个子集,每个子集可以对应一个n位的二进制掩码,每一位的0/1代表对应位置的元素是否被选中:
input_list = [1, 2, 3] list_length = len(input_list) output = [] # 掩码范围从0(二进制000,对应空集)到2^n -1(二进制111,对应全集) for mask in range(1 << list_length): current_subset = [] for idx in range(list_length): # 判断当前位是否为1,为1则把对应元素加入子集 if mask & (1 << idx): current_subset.append(input_list[idx]) output.append(current_subset) print(output)
运行后得到的结果和方法1完全相同。
内容的提问来源于stack exchange,提问作者Data-7scientist
相关产品推荐
相关产品推荐

