如何基于两个集合/列表生成符合值长度限制的集合字典全组合
实现方案
首先根据你的需求分两种常见场景实现,均基于Python标准库itertools即可完成,无额外依赖:
场景1:允许set2元素在不同键的集合中重复出现
该场景逻辑最直接,先为每个键生成所有长度1~n的合法值集合,再对所有键的可选值做笛卡尔积即可覆盖全部组合:
import itertools def generate_dicts(keys, values, max_len): # 生成单个键对应的所有合法值组合(长度从1到max_len) single_key_options = [] for _ in keys: options = [] for length in range(1, max_len + 1): options.extend(list(itertools.combinations(values, length))) single_key_options.append(options) # 对所有键的可选值做笛卡尔积,拼接为字典返回 for combo in itertools.product(*single_key_options): yield dict(zip(keys, combo)) # 测试调用 set1 = ("w1","w2","w3","w4") set2 = ("r1","r2","r3","r4","r5","r6","r7") n = 3 for idx, res in enumerate(generate_dicts(set1, set2, n), 1): print(f"Comb{idx} = {res}")
如果需要值为严格的集合类型,把itertools.combinations返回的元组转为set即可。
场景2:要求set2元素在整个字典的所有值集合中仅出现一次
如果需要所有值集合无重复元素,先生成长度分配方案,再对set2做全排列后按长度切割分配即可:
import itertools def generate_dicts_no_dup(keys, values, max_len): key_cnt = len(keys) val_cnt = len(values) # 先生成合法的长度分配方案:所有键的长度和等于set2元素总数,单个长度不超过max_len for len_combo in itertools.product(range(1, max_len + 1), repeat=key_cnt): if sum(len_combo) != val_cnt: continue # 对set2做全排列,按长度方案切割分配给对应键 for val_perm in itertools.permutations(values): ptr = 0 res = {} for k, l in zip(keys, len_combo): res[k] = set(val_perm[ptr:ptr+l]) ptr += l yield res # 测试调用 set1 = ("w1","w2","w3","w4") set2 = ("r1","r2","r3","r4","r5","r6","r7") n = 3 for idx, res in enumerate(generate_dicts_no_dup(set1, set2, n), 1): print(f"Comb{idx} = {res}")
内容的提问来源于stack exchange,提问作者cppnoob
相关产品推荐
相关产品推荐

