json.loads() doesn't keep order

15,015

Both JSON en Python dictionaries (those are JSON objects) are unordered. So in fact it does not makes any sense to do that, because the JSON encoder can change the order.

You can however define a custom JSON decoder, and then parse it with that decoder. So here the dictionary hook willl be an OrderedDict:

from json import JSONDecoder
from collections import OrderedDict

customdecoder = JSONDecoder(object_pairs_hook=OrderedDict)

Then you can decode with:

customdecoder.decode(your_json_string)

This will thus store the items in an OrderedDict instead of a dictionary. But be aware - as said before - that the order of the keys of JSON objects is unspecified.

Alternatively, you can also pass the hook to the loads function:

from json import loads
from collections import OrderedDict

loads(your_json_string, object_pairs_hook=OrderedDict)

Update: as of , a dictionary retains insertion order. So if one uses , the standard json.load and json.loads should work fine. Note however that a JSON object is still unordered, so that the JavaScript end can load/dump the object in any order.

Share:
15,015
shurrok
Author by

shurrok

Updated on July 16, 2022

Comments

  • shurrok
    shurrok almost 2 years

    I have formatted my String to look like JSON so I could do json.loads on it. When I printed on the screen it turned out it messed up the order. I know that Python dictonaries are not ordered but is there ANY way to keeps this order? I really need to keep it. Thanks!

  • shurrok
    shurrok over 6 years
    what about json.loads(string, object_pairs_hook_=OrderedDict) ?
  • Willem Van Onsem
    Willem Van Onsem over 6 years
    @soommy12: sure, but this is in my opinion a bit against the encapsulation principle. Now you can pass the decoder as an argument, etc.
  • shurrok
    shurrok over 6 years
    Okey, I got the point, thank you very much! :)
  • matanster
    matanster over 2 years
    As of 3.7, python dicts are ordered