I need to do a complete recursive alphabetical ordering on a JSON object in python.
The reason is to be able to diff two json files.
Given this input:
{
    "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}]}]
        }
}
this is the expected output:
{
    "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"
}
EDIT: to be able to do a diff it should order the array elements too.
A JSON object is a simple dict object. Before version 3.7 dicts had no ordering so you first need to convert it to an OrderedDict and then append each json element in the correct order. With 3.7+ you can rely on the standard dict ordering.
Objects with keys are sorted according to their keys, objects inside a list are sorted by their "sorted recursive string representation" while primitive values are sorted according to their natural ordering.
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
The sorting is case sensitive.
You can use it in this way:
json_data = json.loads(json_text)
res = sorted_json(json_data, {})
print(json.dumps(res, indent=4))
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With