如何实现支持任意n个字典的Python嵌套循环组合计算函数?
支持任意数量字典的组合计算函数实现
问题背景
我需要编写一个Python函数,使其能够支持任意数量n的字典进行组合计算。目前已有分别适配3个字典和4个字典的代码示例,但针对n个字典的情况,sets变量需要动态生成,嵌套循环的组合计算逻辑也需适配n的数量,该如何实现?
适配3个字典的代码示例
Dic1 = {'a':0.001,'b':0.999,'c':0.0} Dic2 = {'a':0.018,'b':0.982,'c':0.0} Dic3 = {'a':0.999,'b':0.001,'c':0.0} sets=set(Dic1.keys()).union(set(Dic2.keys())).union(set(Dic3.keys())) print(sets) Result=dict.fromkeys(sets,0) ## Combination process for i in Dic1.keys(): for j in Dic2.keys(): for k in Dic3.keys(): if set(str(i)).intersection(set(str(j))).intersection(set(str(k))) == set(str(i)): Result[i]+=Dic1[i]*Dic2[j]*Dic3[k] elif set(str(i)).intersection(set(str(j))).intersection(set(str(k))) == set(str(j)): Result[j]+=Dic1[i]*Dic2[j]*Dic3[k] elif set(str(i)).intersection(set(str(j))).intersection(set(str(k))) == set(str(k)): Result[k]+=Dic1[i]*Dic2[j]*Dic3[k] f= sum(list(Result.values())) print(f) for i in Result.keys(): Result[i] /=f print(Result)
适配4个字典的代码示例
Dic1 = {'a':0.001,'b':0.999,'c':0.0} Dic2 = {'a':0.018,'b':0.982,'c':0.0} Dic3 = {'a':0.999,'b':0.001,'c':0.0} Dic4 = {'a':0.999,'b':0.001,'c':0.0} sets=set(Dic1.keys()).union(set(Dic2.keys())).union(set(Dic3.keys())).union(set(Dic4.keys())) print(sets) Result=dict.fromkeys(sets,0) ## Combination process for i in Dic1.keys(): for j in Dic2.keys(): for k in Dic3.keys(): for l in Dic4.keys(): if set(str(i)).intersection(set(str(j))).intersection(set(str(k))).intersection(set(str(l))) == set(str(i)): Result[i]+=Dic1[i]*Dic2[j]*Dic3[k]*Dic4[l] elif set(str(i)).intersection(set(str(j))).intersection(set(str(k))).intersection(set(str(l))) == set(str(j)): Result[j]+=Dic1[i]*Dic2[j]*Dic3[k]*Dic4[l] elif set(str(i)).intersection(set(str(j))).intersection(set(str(k))).intersection(set(str(l))) == set(str(k)): Result[k]+=Dic1[i]*Dic2[j]*Dic3[k]*Dic4[l] elif set(str(i)).intersection(set(str(j))).intersection(set(str(k))).intersection(set(str(l))) == set(str(l)): Result[l]+=Dic1[i]*Dic2[j]*Dic3[k]*Dic4[l] f= sum(list(Result.values())) print(f) for i in Result.keys(): Result[i] /=f print(Result)
解决方案
核心逻辑拆解
原有代码的核心逻辑可归纳为:
- 收集所有字典的键的并集,作为结果字典的初始键集合
- 遍历所有字典键的笛卡尔积(即所有可能的键组合)
- 对每个组合,计算所有键的字符集合的交集,找到第一个字符集合与该交集完全匹配的键,将对应字典值的乘积累加到结果的该键中
- 最后将结果归一化(每个值除以总和)
通用实现代码
利用itertools模块的product和chain工具,可实现对任意数量字典的支持:
import itertools def combine_dicts(*dicts): # 动态生成所有键的并集 all_keys = set(itertools.chain.from_iterable(d.keys() for d in dicts)) result = {key: 0.0 for key in all_keys} # 生成所有字典键的笛卡尔积 key_combinations = itertools.product(*(d.keys() for d in dicts)) for combo in key_combinations: # 计算当前组合中所有键的字符集合的交集 char_sets = [set(str(key)) for key in combo] intersection = char_sets[0].intersection(*char_sets[1:]) # 找到第一个字符集合等于交集的键 for idx, key in enumerate(combo): if set(str(key)) == intersection: # 计算当前组合的乘积 product = 1.0 for d, k in zip(dicts, combo): product *= d[k] # 累加到结果中 result[key] += product break # 找到第一个匹配的就停止 # 归一化结果 total = sum(result.values()) if total != 0: for key in result: result[key] /= total return result
测试示例
用原有3个、4个字典的例子验证:
# 测试3个字典的情况 dic1 = {'a':0.001,'b':0.999,'c':0.0} dic2 = {'a':0.018,'b':0.982,'c':0.0} dic3 = {'a':0.999,'b':0.001,'c':0.0} result_3 = combine_dicts(dic1, dic2, dic3) print("3个字典的组合结果:", result_3) # 测试4个字典的情况 dic4 = {'a':0.999,'b':0.001,'c':0.0} result_4 = combine_dicts(dic1, dic2, dic3, dic4) print("4个字典的组合结果:", result_4)
运行结果会和原有代码输出一致,同时支持传入任意数量的字典参数。
内容的提问来源于stack exchange,提问作者Pronob Gohain
相关产品推荐
相关产品推荐

