Python中有什么好的办法比较两个JSON列表的差异?
有 list A 与 list B,list 中的每一个元素是一个 JSON 对象,请问有什么好的方式来比较两个 list 中存在差异的部分呢?
例如:
list A:[json1, json2, josn3]
list B:[json1, json2, josn3]
我想要比较这两个 list 是否完全一样或者存在着怎样的差异,请问最好的解决方式是什么?
Python中有什么好的办法比较两个JSON列表的差异?
把 list 变成 set,再用交集并集运算
import json
from typing import List, Dict, Any, Tuple
def compare_json_lists(list1: List[Dict], list2: List[Dict], key_field: str = None) -> Tuple[List[Dict], List[Dict], List[Dict]]:
"""
比较两个JSON列表的差异
参数:
list1: 第一个JSON列表
list2: 第二个JSON列表
key_field: 用于识别相同记录的关键字段名,如果为None则比较整个字典
返回:
Tuple(added, removed, modified)
added: 在list2中存在但list1中不存在的记录
removed: 在list1中存在但list2中不存在的记录
modified: 在两个列表中都存在但有差异的记录
"""
def create_lookup_dict(lst: List[Dict], key_field: str) -> Dict:
"""创建查找字典,key_field为None时使用整个字典作为key"""
if key_field:
return {item[key_field]: item for item in lst}
else:
# 使用json序列化后的字符串作为key,确保可哈希
return {json.dumps(item, sort_keys=True): item for item in lst}
# 创建查找字典
dict1 = create_lookup_dict(list1, key_field)
dict2 = create_lookup_dict(list2, key_field)
if key_field:
# 使用关键字段比较
keys1 = set(dict1.keys())
keys2 = set(dict2.keys())
added = [dict2[key] for key in keys2 - keys1]
removed = [dict1[key] for key in keys1 - keys2]
# 找出修改的记录
common_keys = keys1 & keys2
modified = []
for key in common_keys:
if dict1[key] != dict2[key]:
modified.append({
'old': dict1[key],
'new': dict2[key],
'key': key
})
else:
# 直接比较整个字典
set1 = set(dict1.keys())
set2 = set(dict2.keys())
added = [dict2[key] for key in set2 - set1]
removed = [dict1[key] for key in set1 - set2]
modified = [] # 当比较整个字典时,要么完全相同要么完全不同
return added, removed, modified
# 使用示例
if __name__ == "__main__":
# 示例数据
old_data = [
{"id": 1, "name": "Alice", "age": 25},
{"id": 2, "name": "Bob", "age": 30},
{"id": 3, "name": "Charlie", "age": 35}
]
new_data = [
{"id": 1, "name": "Alice", "age": 26}, # 年龄修改
{"id": 2, "name": "Bob", "age": 30}, # 未变
{"id": 4, "name": "David", "age": 28} # 新增
]
# 使用id作为关键字段进行比较
added, removed, modified = compare_json_lists(old_data, new_data, key_field="id")
print("新增的记录:", json.dumps(added, indent=2))
print("\n删除的记录:", json.dumps(removed, indent=2))
print("\n修改的记录:", json.dumps(modified, indent=2))
# 也可以不使用关键字段,直接比较整个对象
print("\n--- 不使用关键字段比较 ---")
added2, removed2, modified2 = compare_json_lists(old_data, new_data)
print(f"新增: {len(added2)} 条, 删除: {len(removed2)} 条")
这个方案的核心思路是通过关键字段建立查找字典,用集合操作快速找出差异。如果数据有唯一标识字段(如id),用key_field参数指定;如果没有,就序列化整个字典作为key来比较。返回结果清晰分为新增、删除、修改三部分,修改的记录还会包含新旧值对比。
简单说就是:用字典查找+集合运算,比逐条遍历快得多。
list 中可能存在重复元素,这些元素个数也需要一致。。
先转成字符串再对比?
用 collections.Counter([iterable-or-mapping]) 做做看呢?
那你可以包一个 python 对象再放进 set 里面,这个 python 对象指出 json 在原 list 里面的 index,这样他们的 hash 不一样,甚至你还可以自己再重载一下 hash
这个 https://bitbucket.org/vadim_semenov/json_tools/wiki/Home 或者其他 json 比较的包
把 json load 出来 sort 比较?
我记得有专门比较 json 的库的,GitHub 上面应该能找到。
dictdiffer 可以试试
这个库好👍
感觉就是遍历啊,你用啥都绕不开这个的,只是用起来简便一点而已。
排序一下,格式化成字符串,然后用自带的 diff 库比较,这个库比对差异效率非常高。
谢谢,我待会儿试一下
for x,y in zip(list1,list2):
if x == y:
print(1)
else:
print(0)
#小白表示这样不行吗
原来 V2EX 没法显示缩进
两个 list 顺序可能不一样

