【问题标题】:How to completely sort a JSON tree alphabetically如何按字母顺序对 JSON 树进行完全排序
【发布时间】:2021-04-29 08:46:11
【问题描述】:

我需要在 python 中对 JSON 对象进行完整的递归字母排序。

原因是能够区分两个json文件。

鉴于此输入:

{
    "request-id": "12345",
    "version": "1.1.4",
    "multi": {
            "one": 1, 
            "two": 2.0,
            "Abc": [3,2,4,1, null],
            "three": null,
            "list": [
                        {"lb1": 2.1},
                        {"lb": 2.2}, 
                        {"la": 3}, 
                        {"mix_list": [1, {"bb":1}, 2, {"aa":1}]}]
        }
}

这是预期的输出:

{
    "multi": {
        "Abc": [1,2,3,4,null],
        "list": [
            {"la": 3},
            {"lb": 2.2},
            {"lb1": 2.1},
            { "mix_list": [1, 2, {"aa": 1}, {"bb": 1}] }
        ],
        "one": 1,
        "three": null,
        "two": 2.0
    },
    "request-id": "12345",
    "version": "1.1.4"
}

编辑:为了能够做差异,它也应该对数组元素进行排序。

【问题讨论】:

    标签: python json sorting


    【解决方案1】:

    您可以使用 json.dump/snative kwarg sort_keys 来做到这一点。

    a_json = json.dumps(json_object, sort_keys=True)
    print(a_json)
    

    【讨论】:

    • sort_keys 对键进行排序,但不对数组值进行排序,因此仅区分两个 json 文件是不够的。我澄清了我的问题。
    【解决方案2】:

    JSON 对象是一个简单的 dict 对象。在 3.7 版之前,dicts 没有排序,因此您首先需要将其转换为 OrderedDict,然后以正确的顺序附加每个 json 元素。使用 3.7+,您可以依赖标准的 dict 排序。

    具有键的对象根据它们的键进行排序,列表中的对象根据它们的“排序递归字符串表示”排序,而原始值则根据它们的自然顺序排序。

    import json
    from operator import itemgetter
    
    # replace all three {} with OrderedDict() for python <= 3.6
    
    def sorted_json(js, result):
    
        def norm_str(s):
            # because of str special handling of single quotes
            return str(s).replace("'", '"')
    
        if type(js) in [int, str, bool, float] or js is None:
            return js
    
        if type(js) == list:
            res = [sorted_json(i, {}) for i in js]
            return sorted(res, key=norm_str)
    
        items = sorted(js.items(), key=itemgetter(0))
        for k, v in items:
            result[k] = sorted_json(v, {})
    
        return result
    

    排序区分大小写。

    你可以这样使用:

    json_data = json.loads(json_text)
    res = sorted_json(json_data, {})
    print(json.dumps(res, indent=4))
    

    【讨论】:

    • @superbrain 仅从 3.7 版本开始正式保证订购(在 3.6 中“不应依赖它”)。我会修正我的答案以使其清楚。
    • @superbrain 记住这一点是明智的,以防您想修改两年半之前的 Python 代码。可以说,这仍然是大多数 Python 代码。
    猜你喜欢
    • 1970-01-01
    • 2018-12-07
    • 2019-11-22
    • 1970-01-01
    • 2011-08-29
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多