Apr-05-2019, 12:08 PM
Example of sorting nested dictionary in Python 3.7.
We have three level of dictionaries and we want to sort innermost. In order to do so we have to build new dictionary based on old one by inserting key-value pairs in sorted order to innermost dictionary.
Sample dictionary:
We have three level of dictionaries and we want to sort innermost. In order to do so we have to build new dictionary based on old one by inserting key-value pairs in sorted order to innermost dictionary.
Sample dictionary:
d = {'first_level': {'second_level': {'third_3': 3, 'third_2': 2, 'third_1': 1}}}First we must 'reach' the innermost dictionary. Let's start with second level:
>>> [v.items() for k, v in d.items()] [dict_items([('second_level', {'third_3': 3, 'third_2': 2, 'third_1': 1})])]As we need third level we add one more nesting:
>>> [j.items() for k, v in d.items() for i, j in v.items()] [dict_items([('third_3', 3), ('third_2', 2), ('third_1', 1)])]Now we reached level we want to sort. It's time to use built-in function sorted(). As we can see the elements are tuples where value we want to sort is on index 1 (second element). So we add sorting:
>>> [sorted(j.items(), key=lambda x: x[1]) for k, v in d.items() for i, j in v.items()] [[('third_1', 1), ('third_2', 2), ('third_3', 3)]]We have sorted third level but this ain't nested dictionary what we had at the beginning. So let's add second level back and turn to dictionary comprehension:
>>> {i: dict(sorted(j.items(), key=lambda x: x[1])) for k, v in d.items() for i, j in v.items()} {'second_level': {'third_1': 1, 'third_2': 2, 'third_3': 3}}Lets add first level as well:
>>> {k: {i: dict(sorted(j.items(), key=lambda x: x[1]))} for k, v in d.items() for i, j in v.items()} {'first_level': {'second_level': {'third_1': 1, 'third_2': 2, 'third_3': 3}}}We have constructed new dictionary where third level dictionary is insertion sorted based on values. If we want reverse order then we just add reverse=True:
>>> {k: {i: dict(sorted(j.items(), key=lambda x: x[1], reverse=True))} for k, v in d.items() for i, j in v.items()} {'first_level': {'second_level': {'third_3': 3, 'third_2': 2, 'third_1': 1}}}Readability is not great but steps are quite simple and one should be able to express it as traditional nested for-loop. I should reiterate that (insertion) ordering of dictionary have meaning only starting from Python 3.6 (dictionaries are insertion ordered) and it's only guaranteed to work startind from Python 3.7 (dictionaries are guaranteed to be insertion ordered)
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy
Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.