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

如何仅输出两个JSON对比后的结构化差异化内容?

提取JSON差异并生成指定结构输出(解决dictdiffer TypeError问题)

问题核心

你遇到的问题本质是:dictdiffer返回的差异元组需要针对性解析,再重新构建符合要求的嵌套JSON结构;TypeError通常源于对差异元组结构理解错误,或处理嵌套层级时的类型操作失误。

模拟示例与期望输出

先基于常见场景模拟你的JSON示例和目标输出:

# json1示例
json1 = {
    "user": {
        "name": "Alice",
        "age": 30,
        "contact": {
            "email": "alice@example.com",
            "phone": "123456"
        }
    },
    "settings": {
        "theme": "light"
    }
}

# json2示例
json2 = {
    "user": {
        "name": "Alice",
        "age": 31,
        "contact": {
            "email": "alice_new@example.com",
            "address": "123 St"
        }
    },
    "settings": {
        "theme": "dark",
        "notifications": True
    }
}

# 期望输出(仅保留差异部分,维持原嵌套结构)
{
  "user": {
    "age": 31,
    "contact": {
      "email": "alice_new@example.com",
      "address": "123 St"
    }
  },
  "settings": {
    "theme": "dark",
    "notifications": True
  }
}

解决方案代码

先确保安装dictdiffer:

pip install dictdiffer

然后编写处理逻辑,针对性解析差异元组并构建目标结构:

from dictdiffer import diff
import json

def build_target_diff_structure(differences):
    result = {}
    for diff_type, path, values in differences:
        current_level = result
        # 遍历路径,逐层构建嵌套字典
        for key in path[:-1]:
            if key not in current_level:
                current_level[key] = {}
            current_level = current_level[key]
        last_key = path[-1]
        
        # 按差异类型处理值
        if diff_type == 'change':
            # change类型的values是(旧值, 新值),取新值
            current_level[last_key] = values[1]
        elif diff_type == 'add':
            # add类型的values是[(键, 新值)]的列表
            for k, v in values:
                current_level[k] = v
        elif diff_type == 'remove':
            # 如需保留被删除的键,可设为None或自定义标记;不需要则跳过
            # current_level[last_key] = None
            pass
    return result

# 执行流程
differences = list(diff(json1, json2))
target_diff = build_target_diff_structure(differences)
print(json.dumps(target_diff, indent=2))

TypeError常见原因与调试

  1. 错误解构差异元组:dictdiffer的差异是三元组,change类型的values是二元组,add/remove的values是列表,若错误写成diff_type, path, old_val, new_val会直接报错。
  2. 嵌套层级处理失误:构建嵌套结构时,未先判断当前层级是否为字典就直接赋值,导致类型不匹配。
  3. 忽略差异类型的value结构:比如把add类型的列表直接赋值给键,而非遍历提取内部的键值对。

调试时可先打印差异列表,明确每个元组的结构:

print(differences)
# 输出示例:
# [('change', ['user', 'age'], (30, 31)), ('change', ['user', 'contact', 'email'], ('alice@example.com', 'alice_new@example.com')), ('remove', ['user', 'contact', 'phone'], [('phone', '123456')]), ('add', ['user', 'contact', 'address'], [('address', '123 St')]), ('change', ['settings', 'theme'], ('light', 'dark')), ('add', ['settings', 'notifications'], [('notifications', True)])]

根据实际需求调整build_target_diff_structure函数即可,比如要保留删除的键,取消remove分支的注释即可。

内容的提问来源于stack exchange,提问作者DeLorean

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 14:45:41