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

如何让DeepDiff输出差异时显示对应数据的ID字段?

解决DeepDiff对比列表数据时显示ID而非索引的问题

问题背景

我使用DeepDiff对比两个数据库数据,示例代码如下:

from deepdiff import DeepDiff
users1 = [{'id': 1, 'name': 'John', 'age': 30}, {'id': 2, 'name': 'Jane', 'age': 25}]
users2 = [{'id': 1, 'name': 'John', 'age': 30}, {'id': 2, 'name': 'Bob', 'age': 35}]
diff = DeepDiff(users1, users2)
print(diff)

当前输出仅显示列表索引,无法直接对应到数据的ID:

{'values_changed': {"root[0]['age']": {'new_value': 20, 'old_value': 30}, "root[1]['name']": {'new_value': 'Bob', 'old_value': 'Jane'}, "root[1]['age']": {'new_value': 35, 'old_value': 25}}}

希望输出中能显示对应数据的ID值,明确是哪个ID的记录出现字段差异,比如将路径中的索引替换为ID,或者按ID分组展示差异。


解决方案

方法1:将列表转换为以ID为键的字典(推荐)

DeepDiff对比字典时会直接使用键作为路径的一部分,因此把原列表转成以id为键的字典,就能让差异路径直接显示ID值,无需额外处理。

from deepdiff import DeepDiff

users1 = [{'id': 1, 'name': 'John', 'age': 30}, {'id': 2, 'name': 'Jane', 'age': 25}]
users2 = [{'id': 1, 'name': 'John', 'age': 20}, {'id': 2, 'name': 'Bob', 'age': 35}]

# 转换为以id为键的字典
users1_dict = {user['id']: user for user in users1}
users2_dict = {user['id']: user for user in users2}

diff = DeepDiff(users1_dict, users2_dict)
print(diff)

输出结果(路径中的数字即为ID):

{'values_changed': {"root[1]['age']": {'new_value': 20, 'old_value': 30}, "root[2]['name']": {'new_value': 'Bob', 'old_value': 'Jane'}, "root[2]['age']": {'new_value': 35, 'old_value': 25}}}

方法2:修改DeepDiff的结果,替换索引为ID

如果必须保留原列表结构,可以遍历DeepDiff的结果,将路径中的索引替换为对应的ID值,还可进一步按ID分组展示。

替换路径中的索引为ID

from deepdiff import DeepDiff
import re

users1 = [{'id': 1, 'name': 'John', 'age': 30}, {'id': 2, 'name': 'Jane', 'age': 25}]
users2 = [{'id': 1, 'name': 'John', 'age': 20}, {'id': 2, 'name': 'Bob', 'age': 35}]

diff = DeepDiff(users1, users2)

# 创建索引与ID的映射
index_to_id = {i: user['id'] for i, user in enumerate(users1)}

# 替换values_changed中的路径
if 'values_changed' in diff:
    updated_changes = {}
    for path, change_info in diff['values_changed'].items():
        # 提取路径中的索引
        match = re.search(r'root\[(\d+)\]', path)
        if match:
            index = int(match.group(1))
            target_id = index_to_id.get(index, index)
            # 替换索引为ID
            new_path = path.replace(f'root[{index}]', f'root[{target_id}]')
            updated_changes[new_path] = change_info
    diff['values_changed'] = updated_changes

print(diff)

按ID分组展示差异

如果需要将同一ID的所有差异归类在一起,可进一步处理:

# 基于上面的updated_changes生成按ID分组的结果
grouped_diff = {'values_changed': {}}
for path, change_info in updated_changes.items():
    match = re.search(r'root\[(\d+)\]', path)
    if match:
        target_id = int(match.group(1))
        if target_id not in grouped_diff['values_changed']:
            grouped_diff['values_changed'][target_id] = {}
        grouped_diff['values_changed'][target_id][path] = change_info

print(grouped_diff)

输出结果:

{'values_changed': {1: {"root[1]['age']": {'new_value': 20, 'old_value': 30}}, 2: {"root[2]['name']": {'new_value': 'Bob', 'old_value': 'Jane'}, "root[2]['age']": {'new_value': 35, 'old_value': 25}}}}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 01:19:57