python - 如何以不同的顺序比较具有相同元素的两个 JSON 对象相等?

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

例如...

JSON 文档 a:

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

JSON 文档 b:

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

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

最佳答案

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

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

... 但这不起作用,因为在每种情况下,顶级 dict 的 "errors" 项都是具有不同顺序的相同元素的列表,并且 sorted() 除了可迭代的“顶级”级别之外,不会尝试对任何内容进行排序。

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

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

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

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

https://stackoverflow.com/questions/25851183/

相关文章:

java - jackson + build 者模式?

javascript - 排序对象属性和 JSON.stringify

java - 在 Spring 中配置 ObjectMapper

javascript - 在没有 jQuery 的情况下在 node.js 上合并或合并 JSON

json - 任何用于在 Classic ASP 中解析 JSON 的好库?

java - 将 PostgreSQL JSON 列映射到 Hibernate 实体属性

c# - JavaScriptSerializer.Deserialize - 如何更改字段名称

json - 从 JQuery.ajax 成功数据中解析 JSON

java - 错误 415 不支持的媒体类型 : POST not reaching REST if

json - REST API 最佳实践 : args in query string vs in