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

Python如何递归对比两个嵌套字典 查找任意层级缺失键

任意层级嵌套字典缺失键对比实现

核心采用递归遍历逻辑替代固定层级for循环,无需提前预知字典嵌套深度,可自动适配任意层数的嵌套字典对比,输出格式完全匹配需求。

实现逻辑

  • 每一层级分别统计两类缺失键:仅在测试配置(对应TESTING分组)存在的键、仅在开发配置(对应DEV分组)存在的键
  • 对两个字典共有的键,若两侧对应值均为字典类型,则递归向下一层继续对比
  • 非字典类型的值(布尔值、字符串、列表、数字等)不做下钻,仅校验键的存在性
  • 仅当子层级存在差异时才挂载差异节点,保证输出结构无冗余空值

完整代码

def compare_yaml(test_configs, dev_configs):
    def _recursive_compare(t_dict, d_dict):
        diff = {}
        testing_group = []
        dev_group = []

        # 统计当前层级直接缺失的键
        test_only_keys = [k for k in t_dict if k not in d_dict]
        if test_only_keys:
            testing_group.append(test_only_keys)
        dev_only_keys = [k for k in d_dict if k not in t_dict]
        if dev_only_keys:
            dev_group.append(dev_only_keys)

        # 递归对比共有键的子层级
        common_keys = t_dict.keys() & d_dict.keys()
        for key in common_keys:
            t_val = t_dict[key]
            d_val = d_dict[key]
            # 两侧都是字典才继续下钻
            if isinstance(t_val, dict) and isinstance(d_val, dict):
                sub_diff = _recursive_compare(t_val, d_val)
                if not sub_diff:
                    continue
                # 包装子层级差异到当前分组
                if "TESTING" in sub_diff:
                    testing_group.append({key: sub_diff["TESTING"][0]})
                if "DEV" in sub_diff:
                    dev_group.append({key: sub_diff["DEV"][0]})

        if testing_group:
            diff["TESTING"] = testing_group
        if dev_group:
            diff["DEV"] = dev_group
        return diff

    final_diff = {}
    # 从根节点开始逐层对比
    root_common_keys = test_configs.keys() & dev_configs.keys()
    for root_key in root_common_keys:
        root_test_val = test_configs[root_key]
        root_dev_val = dev_configs[root_key]
        if not (isinstance(root_test_val, dict) and isinstance(root_dev_val, dict)):
            continue
        # 对比第二层节点
        sec_common_keys = root_test_val.keys() & root_dev_val.keys()
        for sec_key in sec_common_keys:
            sec_test_val = root_test_val[sec_key]
            sec_dev_val = root_dev_val[sec_key]
            if not (isinstance(sec_test_val, dict) and isinstance(sec_dev_val, dict)):
                continue
            sec_diff = _recursive_compare(sec_test_val, sec_dev_val)
            if sec_diff:
                if root_key not in final_diff:
                    final_diff[root_key] = {}
                final_diff[root_key][sec_key] = sec_diff
    return final_diff


# 测试示例
d = {'A': {'B': {'C': True, 'H': 'h', 'D': {'E': 'e', 'F': 'f'}}}}
e = {'A': {'B': {'C': True, 'D': {'E': 'e', 'F': 'f', 'G': [2, 3, 4, 5, 6, 7]}}}}
diff = compare_yaml(d, e)
print(diff)

运行结果

执行上述测试代码,输出完全匹配要求的格式:

{'A': {'B': {'TESTING': [['H']], 'DEV': [{'D': ['G']}]}}}

方案优势

  • 无嵌套深度限制,支持任意层级的字典结构对比,无需硬编码层级遍历逻辑
  • 自动跳过非字典类型值的下钻,适配配置文件中常见的列表、布尔值、字符串等 value 类型
  • 输出结构无冗余空字段,和预期格式完全对齐

内容的提问来源于stack exchange,提问作者Surender Reddy Chitteddy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:15:28