如何在使用Python itertools.product()时引入自定义约束条件?
解决方法
方法1:通用过滤方案(适配任意自定义约束)
思路:itertools.product本身不支持直接传入约束参数,我们可以定义单独的校验函数,对生成的每一个组合做校验,仅保留符合要求的结果。这种方案灵活性最高,新增/修改约束只需要调整校验规则即可。
import itertools s = ['1', '2', '3', '4', '!'] # 自定义约束校验函数,所有规则都可以在这里新增 def is_valid(comb): # 约束1:不以!开头,comb[0]为第一位字符 if comb[0] == '!': return False # 约束2:第三位字符必须是3,Python索引从0开始,第三位对应索引2 if comb[2] != '3': return False # 其他自定义约束示例:要求至少包含1个!,不需要可以删除 # if '!' not in comb: # return False # 其他自定义约束示例:不能出现连续两个相同字符,不需要可以删除 # for i in range(len(comb)-1): # if comb[i] == comb[i+1]: # return False return True # 不需要提前转list占用内存,直接迭代过滤即可 with open('output1.txt', 'w') as f: for comb in itertools.product(s, repeat=4): if is_valid(comb): f.write(''.join(comb) + '\n')
方法2:拆分生成逻辑(更高性能,适合固定位置约束)
思路:如果约束是针对固定位置的取值限制,可以直接拆分每个位置的可选字符集合,从生成阶段就避免无效组合产生,不需要后续过滤,性能远高于第一种方案,适合组合量级较大的场景。
import itertools s = ['1', '2', '3', '4', '!'] # 拆分每个位置的可选字符集合 pos1_options = [c for c in s if c != '!'] # 第一位不能是! pos2_options = s # 第二位无限制 pos3_options = ['3'] # 第三位固定为3 pos4_options = s # 第四位无限制 with open('output1.txt', 'w') as f: for comb in itertools.product(pos1_options, pos2_options, pos3_options, pos4_options): f.write(''.join(comb) + '\n')
两种方案都可以实现需求,如果约束涉及跨位置判断(比如不能有重复字符、特殊字符数量要求等),只能使用第一种通用过滤方案。
内容的提问来源于stack exchange,提问作者SeaDude
相关产品推荐
相关产品推荐

