You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从含字符串、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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:09:55