Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How, or can, I get python -mjson.tool to maintain the order of the attributes

I know little of python other than this simple invocation: python -m json.tool {someSourceOfJSON}

Note how the source document is ordered "id", "z", "a" but the resulting JSON document presents the attributes "a", "id", "z".

$ echo '{ "id": "hello", "z": "obj", "a": 1 }' | python -m json.tool
{
    "a": 1,
    "id": "hello",
    "z": "obj"
}

How, or can, I make the json.tool thing maintain the order of the attributes from the original JSON document?

The python version is whatever comes with this MacBookPro

$ python --version
Python 2.7.15
like image 768
Bob Kuhar Avatar asked Sep 02 '25 11:09

Bob Kuhar


1 Answers

I'm not sure if it's possible with python -m json.tool but is with a one liner (which I'm guessing is the actual X/Y root problem) :

echo '{ "id": "hello", "z": "obj", "a": 1 }' | python -c "import json, sys, collections; print(json.dumps(json.loads(sys.stdin.read(), object_pairs_hook=collections.OrderedDict), indent=4))"

Result:

{
    "id": "hello",
    "z": "obj",
    "a": 1
}

This is essentially the following code, but without the immediate objects and some readability compromises, such as oneline imports.

import json
import sys
import collections

# Read from stdin / pipe as a str
text = sys.stdin.read()

# Deserialise text to a Python object.
# It's most likely to be a dict, depending on the input
# Use `OrderedDict` type to maintain order of dicts.
my_obj = json.loads(text, object_pairs_hook=collections.OrderedDict)

# Serialise the object back to text
text_indented = json.dumps(my_obj, indent=4)

# Write it out again
print(text_indented)
like image 56
Alastair McCormack Avatar answered Sep 04 '25 00:09

Alastair McCormack