如何高效迭代指定元素数量的多列表子集组合
如何高效迭代指定元素数量的多列表子集组合
嘿,这个需求其实用Python的标准库就能高效搞定,完全不用自己写复杂的循环逻辑!核心思路就是先给每个列表生成对应数量的子集组合,再把这些组合做笛卡尔积,最后把结果平展成你需要的格式就行。
具体实现步骤
首先我们要用到itertools模块里的两个实用工具:
combinations:用来生成单个列表中指定长度的所有子集组合(不考虑元素顺序)product:用来把多个组合集合做笛卡尔积,也就是把每个列表的组合两两配对
直接实现的示例代码
先导入模块并定义你的列表:
import itertools A = [1, 4, 5] # 取1个元素 B = [7, 2, 12, 16] # 取1个元素 C = [10, 24, 26, 31, 45, 51] # 取2个元素
然后生成所有组合并遍历:
# 先分别生成每个列表的目标组合 combo_A = itertools.combinations(A, 1) combo_B = itertools.combinations(B, 1) combo_C = itertools.combinations(C, 2) # 把三个组合集合做笛卡尔积,再平展每个结果 for a, b, c in itertools.product(combo_A, combo_B, combo_C): result = a + b + c print(result)
运行这段代码,你就能得到像(1, 7, 10, 24)、(1, 7, 10, 26)这样的结果,完全符合你的需求。
封装成通用函数
如果你需要经常用这个功能,可以把它封装成你示例里的get_combinations函数,调用起来更灵活:
import itertools def get_combinations(*args): # 传入的参数是多个 (取元素数量, 目标列表) 的元组 # 先为每个列表生成对应的组合生成器 combo_generators = [itertools.combinations(lst, cnt) for cnt, lst in args] # 遍历笛卡尔积的结果,平展成单个元组后返回 for combo_tuple in itertools.product(*combo_generators): yield sum(combo_tuple, ()) # 调用方式和你示例里的完全一致 A = [1, 4, 5] B = [7, 2, 12, 16] C = [10, 24, 26, 31, 45, 51] for i in get_combinations((1,A), (1,B), (2,C)): print(i)
为什么这个方法高效?
itertools里的函数都是用C实现的,比纯Python写的循环快很多,处理大数据量时性能差距尤其明显- 所有生成器都是惰性求值的,不会一次性把所有组合都加载到内存里,就算列表很大也不会出现内存溢出的问题
备注:内容来源于stack exchange,提问作者Lupacs
相关产品推荐
相关产品推荐

