Search code examples
pythonordereddictionaryujson

I want to keep order of OrderedDict with ujson


My function's return value type is OrderedDict,

and now I want to write this on the file:

Here's my code:

mainDict = OrderedDict([('a',1),('b',2),('c',3),('d',[4,5,6])])
with open(outFileName, 'w', encoding='utf-8') as outFile :
   outFile.write(ujson.dumps(mainDict, indent=4))

I expected it to keep the order of the dictionary in the file, but it got mixed up.

Is it because of using ujson.dumps? and how can I keep the order of an OrderedDict in the output file?


Solution

  • Use sort_keys parameter of ujson.dumps

    Behaviour of ujson is the following:

    • sort_keys=None (default if omitted) - dump dict keys in implementation-defined order, which may be different every launch (but it's fast)
    • sort_keys=True - sort dict keys before dump
    • sort_keys=False - preserve dict keys order provided by dict.items()

    So to preserve ordering of OrderedDict with ujson, you need sort_keys=False.


    Tests

    This is how you can check it:

    import sys
    import ujson
    
    order = None
    if len(sys.argv) == 2:
        order = bool(int(sys.argv[1]))
    
    mainDict = OrderedDict([('c',3),('b',2),('a',1)])
    sys.stdout.write(ujson.dumps(mainDict, sort_keys=order))
    

    Tests:

    $ python order.py      # sort_keys=None
    {"c":3,"a":1,"b":2}
    
    $ python order.py      # sort_keys=None
    {"b":2,"c":3,"a":1}
    
    $ python order.py 1    # sort_keys=True
    {"a":1,"b":2,"c":3}
    
    $ python order.py 0    # sort_keys=False
    {"c":3,"b":2,"a":1}
    

    Notes

    Note that unlike ujson, built-in json module preserves key order with sort_keys=None, as well as with sort_keys=False.

    Also note that although it's possible to preserve keys order with these implementations (ujson and json), it's non-standard JSON. See json.org:

    An object is an unordered set of name/value pairs.