如何以不同的顺序比较具有相同元素的两个 JSON 对象相等? [英] How to compare two JSON objects with the same elements in a different order equal?

查看:47
本文介绍了如何以不同的顺序比较具有相同元素的两个 JSON 对象相等?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在python中测试两个JSON对象是否相等,不考虑列表的顺序?

例如...

JSON 文档a:

<代码>{错误":[{错误":无效",字段":电子邮件"},{"error": "required", "field": "name"}],成功":假}

JSON 文档b:

<代码>{成功":错误,错误":[{"error": "required", "field": "name"},{错误":无效",字段":电子邮件"}]}

ab 应该比较相等,即使 "errors" 列表的顺序不同.

解决方案

如果您希望具有相同元素但顺序不同的两个对象比较相等,那么显而易见的事情就是比较它们的已排序副本 - 例如, 对于由您的 JSON 字符串 ab 表示的字典:

导入jsona = json.loads("""{错误":[{错误":无效",字段":电子邮件"},{"error": "required", "field": "name"}],成功":假}""")b = json.loads("""{成功":错误,错误":[{"error": "required", "field": "name"},{错误":无效",字段":电子邮件"}]}""")

<预><代码>>>>排序(a.items())==排序(b.items())错误的

... 但这不起作用,因为在每种情况下,顶级字典的 "errors" 项都是一个列表,其中元素的顺序不同,而 sorted() 不会尝试对可迭代对象的顶级"级别以外的任何内容进行排序.

为了解决这个问题,我们可以定义一个 ordered 函数,该函数将对它找到的任何列表进行递归排序(并将字典转换为 (key, value) 对的列表,以便他们是可订购的):

def 排序(对象):如果是实例(对象,字典):返回 sorted((k,ordered(v)) for k, v in obj.items())如果是实例(对象,列表):return sorted(ordered(x) for x in obj)别的:返回对象

如果我们将此函数应用于ab,结果比较相等:

<预><代码>>>>有序(a)==有序(b)真的

How can I test whether two JSON objects are equal in python, disregarding the order of lists?

For example ...

JSON document a:

{
    "errors": [
        {"error": "invalid", "field": "email"},
        {"error": "required", "field": "name"}
    ],
    "success": false
}

JSON document b:

{
    "success": false,
    "errors": [
        {"error": "required", "field": "name"},
        {"error": "invalid", "field": "email"}
    ]
}

a and b should compare equal, even though the order of the "errors" lists are different.

解决方案

If you want two objects with the same elements but in a different order to compare equal, then the obvious thing to do is compare sorted copies of them - for instance, for the dictionaries represented by your JSON strings a and b:

import json

a = json.loads("""
{
    "errors": [
        {"error": "invalid", "field": "email"},
        {"error": "required", "field": "name"}
    ],
    "success": false
}
""")

b = json.loads("""
{
    "success": false,
    "errors": [
        {"error": "required", "field": "name"},
        {"error": "invalid", "field": "email"}
    ]
}
""")

>>> sorted(a.items()) == sorted(b.items())
False

... but that doesn't work, because in each case, the "errors" item of the top-level dict is a list with the same elements in a different order, and sorted() doesn't try to sort anything except the "top" level of an iterable.

To fix that, we can define an ordered function which will recursively sort any lists it finds (and convert dictionaries to lists of (key, value) pairs so that they're orderable):

def ordered(obj):
    if isinstance(obj, dict):
        return sorted((k, ordered(v)) for k, v in obj.items())
    if isinstance(obj, list):
        return sorted(ordered(x) for x in obj)
    else:
        return obj

If we apply this function to a and b, the results compare equal:

>>> ordered(a) == ordered(b)
True

这篇关于如何以不同的顺序比较具有相同元素的两个 JSON 对象相等?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆