MERose
MERose

Reputation: 4421

Keep input order in nested dictionaries

How can I preserve the input order of nested dictionaries? Specifically: I use another dictionary to make it the nested dictionary of an ordered dict (named 'outdict'), and then I add new keys.

Example data:

example1 = {'x': '28', 'y': 9,'z': '1999'}
example2 = {'x': '12', 'y': 15,'z': '2000'}
test1 = "abc"
test2 = "def"

My desired form of 'outdict' is

{'one': {'x': '28', 'y': 9,'z': '1999', 'alpha': 'abc'},
 'two': {'x': '12', 'y': 15,'z': '2000', 'alpha': 'def'}}

I tried two things:

1.

from collections import OrderedDict

class MyDict(OrderedDict):
    def __missing__(self, key):
        val = self[key] = MyDict()
        return val

outdict = MyDict()
outdict["one"].update(OrderedDict(example1))
outdict["one"]["alpha"] = test1
outdict["two"].update(OrderedDict(example2))
outdict["two"]["alpha"] = test2

(from https://stackoverflow.com/questions/18809482#18809656) Result: Not sorted

2.

outdict = OrderedDict()
outdict["one"] = OrderedDict()
outdict["two"] = OrderedDict()
outdict["one"].update(OrderedDict(example1))
outdict["one"]["alpha"] = test1
outdict["two"].update(OrderedDict(example2))
outdict["two"]["alpha"] = test2

Result: Not sorted

Upvotes: 2

Views: 1356

Answers (2)

tobias_k
tobias_k

Reputation: 82929

Putting the content of a regular unordered dict into an ordered dict will not magically restore the order of the values in the unordered dict.

There are some things you could do, though:

  1. Create example1 as an OrderedDict, too, so its values are ordered; but pass the items as a list, not as a dict, or they will be unordered again before the 'arrive' in the ordered dict

    example1 = OrderedDict([('x', '28'), ('y', 9), ('z', '1999')])
    
  2. If you want the values to be ordered alphabetically, and not necessarily in the order they were added, you can just sort the items and create a new OrderedDict from that...

    example1 = OrderedDict(sorted(example1.items()))
    
  3. ... or skip that step and update your outer dict with the sorted items directly

    outdict["one"].update(sorted(example1.items()))
    

Upvotes: 3

Gil
Gil

Reputation: 380

You can't just take a regular dict and wrap it in an OrderedDict(). This will not restore the order of the values. You need to use an ordered dict from the beginning. Example:

Originally we had...

>>> example1 = {'x':'28','y':'9','z':'1999'}
>>> example1
{'y': '9', 'x': '28', 'z': '1999'}

Now with the OrderedDict()

>>> from collections import OrderedDict
>>> example2 = OrderedDict()
>>> example2['x']=28
>>> example2['y']=9
>>> example2['z']=1999
>>> example2
OrderedDict([('x', 28), ('y', 9), ('z', 1999)])

Upvotes: 1

Related Questions