Python Forum

Full Version: Sort MULTIDIMENSIONAL Dictionary
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi all,

Im trying to order a Multidimensional dictionary with no success. I get the dict by a function and the result is like this:

Output:
{'Num_Subdir': 11, 'Path': '/root/git/dir1', 'RealSize': '236K', 'Subdir': {'1234': {'Num_Subdir': 10, 'Path': '/root/git/dir1/1234', 'RealSize': '44K', 'Subdir': {'ola000': {'Num_Subdir': 0, 'Path': '/root/git/dir1/1234/ola000', 'RealSize': '4,0K', 'Subdir': {}}, 'ola00sd1': {'Num_Subdir': 0, 'Path': '/root/git/dir1/1234/ola00sd1', 'RealSize': '4,0K', 'Subdir': {}}, 'ola00sdf': {'Num_Subdir': 0, 'Path': '/root/git/dir1/1234/ola00sdf', 'RealSize': '4,0K', 'Subdir': {}}, 'ola1': {'Num_Subdir': 0, 'Path': '/root/git/dir1/1234/ola1', 'RealSize': '4,0K', 'Subdir': {}}, 'ola2': {'Num_Subdir': 0, 'Path': '/root/git/dir1/1234/ola2', 'RealSize': '4,0K', 'Subdir': {}}, 'ola5': {'Num_Subdir': 0, 'Path': '/root/git/dir1/1234/ola5', 'RealSize': '4,0K', 'Subdir': {}}, 'ola6': {'Num_Subdir': 0, 'Path': '/root/git/dir1/1234/ola6', 'RealSize': '4,0K', 'Subdir': {}}, 'ola7': {'Num_Subdir': 0, 'Path': '/root/git/dir1/1234/ola7', 'RealSize': '4,0K', 'Subdir': {}}, 'ola8': {'Num_Subdir': 0, 'Path': '/root/git/dir1/1234/ola8', 'RealSize': '4,0K', 'Subdir': {}}, 'ola9': {'Num_Subdir': 0, 'Path': '/root/git/dir1/1234/ola9', 'RealSize': '4,0K', 'Subdir': {}}}}, 'cece': {'Num_Subdir': 0, 'Path': '/root/git/dir1/cece', 'RealSize': '4,0K', 'Subdir': {}}, 'dir11': {'Num_Subdir': 7, 'Path': '/root/git/dir1/dir11', 'RealSize': '32K', 'Subdir': {'ola1': {'Num_Subdir': 0, 'Path': '/root/git/dir1/dir11/ola1', 'RealSize': '4,0K', 'Subdir': {}}, 'ola2': {'Num_Subdir': 0, 'Path': '/root/git/dir1/dir11/ola2', 'RealSize': '4,0K', 'Subdir': {}}, 'ola3': {'Num_Subdir': 0, 'Path': '/root/git/dir1/dir11/ola3', 'RealSize': '4,0K', 'Subdir': {}}, 'ola5': {'Num_Subdir': 0, 'Path': '/root/git/dir1/dir11/ola5', 'RealSize': '4,0K', 'Subdir': {}}, 'ola6': {'Num_Subdir': 0, 'Path': '/root/git/dir1/dir11/ola6', 'RealSize': '4,0K', 'Subdir': {}}, 'ola7': {'Num_Subdir': 0, 'Path': '/root/git/dir1/dir11/ola7', 'RealSize': '4,0K', 'Subdir': {}}, 'ola9': {'Num_Subdir': 0, 'Path': '/root/git/dir1/dir11/ola9', 'RealSize': '4,0K', 'Subdir': {}}}},
Is bigger but, i only put a bit of the code. Well, now i need to order the dictionary, or the output by Num_Subdir of the root directories, so in the output the first one to show should be the directory with more 'Num_Subdir'. Im using python 3.6 and im tried too many options with no succes..
I need a helping hand!

Thanks.
Sorting dictionaries is usually making little sense. However, starting from Python 3.7 dictionaries are guaranteed to be in insertion order. So - if you want 'sorted dictionary' then you should build new dictionary by inserting key-value pairs in sorted order.

Still, it seems to me that you actually not wanting to sort dictionary. It seems to me that you actually want sort list (of dictionaries). Meaning that list elements (which happens to be nested dictionaries) must be ordered based on some value in nested dictionary. Is it so? Do you want sort list of dictionaries based on value on first row 'Num_Subdir': 11 in nested dictionary?
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:

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)