如何用itertools生成带重复、递增长度的元素组合并添加分隔符
生成允许重复的多长度元素组合并添加分隔符
问题描述
我尝试用itertools生成一个列表,包含原列表元素允许重复、长度从1到指定值递增的所有组合,并用指定分隔符连接元素,但一直没成功。
示例
lis = ['a','b','c'] separator = '/' total_number_of_combinations = 3 # 期望生成的列表 permutation_list = ['a','b','c', 'a/a', 'a/b', 'a/c', 'b/a', 'b/b', 'b/c', 'c/a', 'c/b', 'c/c', 'a/a/a', 'a/a/b', 'a/a/c', 'a/b/a', 'a/b/b', 'a/b/c', 'a/c/a', 'a/c/b', 'a/c/c', 'b/a/a', 'b/a/b', 'b/a/c', 'b/b/a', 'b/b/b', 'b/b/c', 'b/c/a', 'b/c/b', 'b/c/c', 'c/a/a', 'c/a/b', 'c/a/c', 'c/b/a', 'c/b/b', 'c/b/c', 'c/c/a', 'c/c/b', 'c/c/c']
该列表的元素总数公式为:len(lis) + len(lis)**2 + len(lis)**3 + ... + len(lis)**n,其中n = total_number_of_combinations。
我需要:
- 分隔符和
total_number_of_combinations可灵活修改 - 生成的列表能直接用于Pandas DataFrame的过滤(如
dt[dt.my_col.isin(permutation_list)])
实际场景
lis = ['BRUTELE','COCKPIT EST', 'CIRCET'] separator = ' / ' total_number_of_combinations = 10 # 最终需生成88572个元素的列表
解决方案
你要的是可重复的笛卡尔积,使用itertools.product即可实现,只需遍历从1到指定长度的所有取值,对每个长度生成笛卡尔积后用分隔符拼接即可。
代码实现:
import itertools def generate_combination_list(lis, separator, max_length): result = [] for length in range(1, max_length + 1): # 生成对应长度的可重复笛卡尔积 for combo in itertools.product(lis, repeat=length): result.append(separator.join(combo)) return result # 测试示例场景 lis = ['a','b','c'] separator = '/' total_number_of_combinations = 3 permutation_list = generate_combination_list(lis, separator, total_number_of_combinations) print(len(permutation_list)) # 输出39,与示例元素总数一致 # 实际场景调用 lis_real = ['BRUTELE','COCKPIT EST', 'CIRCET'] separator_real = ' / ' total_real = 10 result_real = generate_combination_list(lis_real, separator_real, total_real) print(len(result_real)) # 输出88572,符合需求
关键说明
itertools.product(lis, repeat=length):生成所有长度为length的可重复元素组合,保留顺序(比如a/b和b/a都会被生成),完全匹配你的需求separator.join(combo):将笛卡尔积的元组元素用指定分隔符拼接成字符串- 遍历1到
max_length的所有长度,确保覆盖所有递增长度的组合
性能提示
当max_length较大时(比如10),元素数量会指数级增长,生成列表时注意内存占用。如果仅用于Pandas过滤,也可以考虑用生成器配合pd.Series.str.contains做模糊匹配,但精准匹配场景下,直接生成列表是最可靠的方式。
内容的提问来源于stack exchange,提问作者Cayo Emilio
相关产品推荐
相关产品推荐

