Can I get JSON to load into an OrderedDict? Can I get JSON to load into an OrderedDict? python python

Can I get JSON to load into an OrderedDict?


Yes, you can. By specifying the object_pairs_hook argument to JSONDecoder. In fact, this is the exact example given in the documentation.

>>> json.JSONDecoder(object_pairs_hook=collections.OrderedDict).decode('{"foo":1, "bar": 2}')OrderedDict([('foo', 1), ('bar', 2)])>>> 

You can pass this parameter to json.loads (if you don't need a Decoder instance for other purposes) like so:

>>> import json>>> from collections import OrderedDict>>> data = json.loads('{"foo":1, "bar": 2}', object_pairs_hook=OrderedDict)>>> print json.dumps(data, indent=4){    "foo": 1,    "bar": 2}>>> 

Using json.load is done in the same way:

>>> data = json.load(open('config.json'), object_pairs_hook=OrderedDict)


Simple version for Python 2.7+

my_ordered_dict = json.loads(json_str, object_pairs_hook=collections.OrderedDict)

Or for Python 2.4 to 2.6

import simplejson as jsonimport ordereddictmy_ordered_dict = json.loads(json_str, object_pairs_hook=ordereddict.OrderedDict)


Some great news! Since version 3.6 the cPython implementation has preserved the insertion order of dictionaries (https://mail.python.org/pipermail/python-dev/2016-September/146327.html). This means that the json library is now order preserving by default. Observe the difference in behaviour between python 3.5 and 3.6. The code:

import jsondata = json.loads('{"foo":1, "bar":2, "fiddle":{"bar":2, "foo":1}}')print(json.dumps(data, indent=4))

In py3.5 the resulting order is undefined:

{    "fiddle": {        "bar": 2,        "foo": 1    },    "bar": 2,    "foo": 1}

In the cPython implementation of python 3.6:

{    "foo": 1,    "bar": 2,    "fiddle": {        "bar": 2,        "foo": 1    }}

The really great news is that this has become a language specification as of python 3.7 (as opposed to an implementation detail of cPython 3.6+): https://mail.python.org/pipermail/python-dev/2017-December/151283.html

So the answer to your question now becomes: upgrade to python 3.6! :)