比较两个 JSON 对象,忽略它们中元素的顺序

32

是否有任何在Python中比较两个JSON对象并打印出它们的变化/差异的方式/类/模块?

我尝试了“json_tools”,它给出了相当不错的结果,但是如果两个JSON对象中有元素顺序不同的Python列表,则diff会失败。

例如:

JSON 1:

{
    'Person' : 
        {
            'FName'    : 'John',
            'LName'    : 'Rambo',
            'Sex'      : 'Male'
            'Height'   : '6 ft',
            'Weight'   : '90 KG',
            'Children' :
                [
                    {
                        'FName'  : 'Anna',
                        'LName'  : 'Rambo',
                        'Sex'    : 'Female',
                        'Height' : '5 ft',
                        'Weight' : '55 KG',
                    },
                    {
                        'FName'  : 'Jemmy',
                        'LName'  : 'Rambo',
                        'Sex'    : 'Male',
                        'Height' : '5 ft',
                        'Weight' : '60 KG',
                    }

                ]
        }
}

JSON 2:

{
    'Person' : 
        {
            'FName'    : 'John',
            'LName'    : 'Rambo',
            'Sex'      : 'Male'
            'Height'   : '6 ft',
            'Weight'   : '90 KG',
            'Children' :
                [
                    {
                        'FName'  : 'Jemmy',
                        'LName'  : 'Rambo',
                        'Sex'    : 'Male',
                        'Height' : '5 ft',
                        'Weight' : '60 KG',
                    },
                    {
                        'FName'  : 'Anna',
                        'LName'  : 'Rambo',
                        'Sex'    : 'Female',
                        'Height' : '5 ft',
                        'Weight' : '55 KG',
                    }
                ]
        }
}

JSON差异显示两个JSON不匹配,但逻辑上它们是相同的。

在Python中有一种好的方式来匹配和比较JSON吗?

4个回答

27

你可以使用jsondiff

from jsondiff import diff
diff(json1, json2)

假设您已经加载了json1和json2,并且这些json条目与您的示例相同(顺便提一下,在“sex”条目之后,您缺少逗号)。


1
很棒的答案!帮助我比较了两个自动生成的 JSON 文件,并一直处理差异,直到 "diff" 输出为空,就像我想要的一样。 - Capt. Crunch
我发现这个链接更有帮助:https://dev59.com/TV8e5IYBdhLWcg3wVJMC#25851972 - Akhilraj N S
这个能在嵌套的JSON对象数组上工作吗? - sattva_venu

17

你可以使用deepdiff并将ignore_order=True

from deepdiff import DeepDiff
t1 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 2, 3]}}
t2 = {1:1, 2:2, 3:3, 4:{"a":"hello", "b":[1, 3, 2, 3]}}
ddiff = DeepDiff(t1, t2, ignore_order=True)
print (ddiff)
{}

1
t1 中,_[1, 2, 3]_ 和在 t2 中的 [1, 3, 2, 3] 之间存在差异。为什么输出为空? - Afsan Abdulali Gujarati
4
如果您希望被警告重复内容,您可以添加 report_repetition=True。请参阅相关文档。 - Nir Soudry
deepdiff 看起来很不错,谢谢。 - odigity

9

逻辑上它们是相同的。

但实际上并不相同,因为在JSON数组中顺序很重要。我不知道有哪些工具可以忽略顺序。你可以尝试对反序列化后的结构进行递归处理,将列表转换成某种多集合类型,将字典转换成可哈希的冻结字典(以便放入多集合中),然后在此基础上运行自己的差异比较程序。


我们如何通过忽略某些键来使用它? - Bimlesh Sharma

3

您可以尝试对json.dumps(jobj, sort_keys=True)的结果进行diff。


1
sort_keys 不会重新排序 JSON 数组;它只影响 JSON 对象键值对序列化的顺序。 - user2357112

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接