如何从含字符串、None、列表及列表的列表的复杂字典生成所有组合?
嘿,我明白你的需求了——把一个混合了字符串、None、普通列表和配对列表组的字典,展开成所有可能排列的字典列表,特别是要处理varName和varVal这种长度对应的列表组合对吧?我给你写了个Python实现,附带思路、示例和注意事项,应该能解决你的问题~
思路分析
首先得把输入字典里的元素分成三类处理:
- 固定值:字符串、
None这类不需要展开的元素,直接保留原值 - 单值列表:比如
[1,2]这种普通列表,每个元素作为一个独立的选项 - 配对列表组:
varName和varVal,需要生成每个varName对应varVal子列表元素的笛卡尔积组合,严格保证两者长度一致
代码实现
import itertools def expand_dict(input_dict): # 初始化各部分存储容器 fixed_items = {} list_expansions = [] var_combos = [] # 拆分输入字典中的元素 for key, value in input_dict.items(): if key == "varName": # 暂存变量名,后续和varVal配对 var_names = value elif key == "varVal": # 校验varName和varVal长度是否一致(可选,按需开启) # if len(var_names) != len(value): # raise ValueError("varName and varVal must have the same length") # 生成varVal子列表的笛卡尔积,再转成对应varName的字典 var_product = itertools.product(*value) var_combos = [dict(zip(var_names, combo)) for combo in var_product] elif isinstance(value, list) and (not value or not isinstance(value[0], list)): # 处理普通单值列表,每个元素转成独立的键值对选项 list_expansions.append([{key: item} for item in value]) else: # 固定值直接存入:字符串、None、非列表类型等 fixed_items[key] = value # 整合所有需要展开的部分 expand_parts = [] if var_combos: expand_parts.append(var_combos) expand_parts.extend(list_expansions) # 如果没有需要展开的内容,直接返回包含原固定值的列表 if not expand_parts: return [fixed_items] # 计算所有展开部分的笛卡尔积,合并生成最终字典 result = [] for combo in itertools.product(*expand_parts): merged_dict = fixed_items.copy() for part in combo: merged_dict.update(part) result.append(merged_dict) return result
示例测试
拿一个典型的输入字典来测试:
test_input = { "experiment_name": "model_tuning", "note": None, "batch_size": [32, 64], "varName": ["learning_rate", "optimizer"], "varVal": [[0.001, 0.01], ["adam", "sgd"]] } # 调用函数获取结果 expanded_dicts = expand_dict(test_input)
输出的结果会是8个字典(2个batch_size选项 × 2×2个var组合),每个字典都是唯一的排列:
[ {"experiment_name": "model_tuning", "note": None, "batch_size": 32, "learning_rate": 0.001, "optimizer": "adam"}, {"experiment_name": "model_tuning", "note": None, "batch_size": 32, "learning_rate": 0.001, "optimizer": "sgd"}, {"experiment_name": "model_tuning", "note": None, "batch_size": 32, "learning_rate": 0.01, "optimizer": "adam"}, {"experiment_name": "model_tuning", "note": None, "batch_size": 32, "learning_rate": 0.01, "optimizer": "sgd"}, {"experiment_name": "model_tuning", "note": None, "batch_size": 64, "learning_rate": 0.001, "optimizer": "adam"}, {"experiment_name": "model_tuning", "note": None, "batch_size": 64, "learning_rate": 0.001, "optimizer": "sgd"}, {"experiment_name": "model_tuning", "note": None, "batch_size": 64, "learning_rate": 0.01, "optimizer": "adam"}, {"experiment_name": "model_tuning", "note": None, "batch_size": 64, "learning_rate": 0.01, "optimizer": "sgd"} ]
注意事项
- 如果你需要严格校验
varName和varVal的长度一致性,可以把代码里的注释校验逻辑打开 - 单值列表的判断逻辑是
isinstance(value, list) and (not value or not isinstance(value[0], list)),如果你的列表存在混合类型(比如既有子列表又有单个值),可以根据实际需求调整这个判断 None会被当作固定值直接保留,完全符合你提到的“None相关问题已得到处理”的需求
内容的提问来源于stack exchange,提问作者Scott G
相关产品推荐
相关产品推荐

