How do you sort a nested dictionary in Python by key or by value?
Throughout this article, I will use the following example, which displays a nested dictionary that contains three main properties labelled
dict1
,
dict2
,
dict3
and from each key they reference another dictionary which contains a simple dictionary of three keys labelled
A
,
B
and
C
with each key matched to the same value
1
,
2
and
3
:
nested_dict = { 'dict1': {'A': 1, 'C': 3, 'B': 2}, 'dict2': {'C': 3, 'A': 1, 'B': 2}, 'dict3': {'C': 1, 'B': 1, 'A': 1} }
The idea with this nested dictionary is to correctly set each of the
dict1
,
dict2
and
dict3
properties such that their dictionary is
{'A': 1, 'B': 2, 'C': 3}
except for
dict3
, which will be used to determine if sorting by key has worked.
Start With A Dict Comprehension
To get started with sorting a nested dictionary you need to loop through each of the main properties (
dict1
,
dict2
and
dict3
in my case). To accomplish this I’m going to use a dict comprehension, which is simply:
{key: value for key, value in nested_dict.items()}
With a dict comprehension you can iterate through each of the main properties on the
nested_dict
variable using the
.items()
dictionary method.
Here’s what the above code produces in a Python REPL:
>>> nested_dict = {'dict1': {'A': 1, 'C': 3, 'B': 2}, 'dict2': {'C': 3, 'A': 1, 'B': 2}, 'dict3': {'C': 1, 'B': 1, 'A': 1}}
>>> {key: value for key, value in nested_dict.items()}
{'dict1': {'A': 1, 'C': 3, 'B': 2}, 'dict2': {'C': 3, 'A': 1, 'B': 2}, 'dict3': {'C': 1, 'B': 1, 'A': 1}}
Notice the result is the same as the
nested_dict
variable and this is important as you now have the ability to loop through each of the components in your original dict.
Sort Nested Dictionaries By Value
Therefore, to sort the nested dictionary by its values I will apply the same
.items()
method but will use them on the original dictionary’s
values
.
Here’s what I mean and this time I’m going to swap the dict comprehension to a list comprehension by outputting
values.items()
like so:
>>> [value.items() for key, value in nested_dict.items()]
[dict_items([('A', 1), ('C', 3), ('B', 2)]),
dict_items([('C', 3), ('A', 1), ('B', 2)]),
dict_items([('C', 1), ('B', 1), ('A', 1)])]
Notice here that the
.items()
method exposes a list of tuples where the first item in the tuple is the key and the second item is the value. Therefore, to sort each dictionary by its values you will want to sort based on the second item in the tuple.
Using the
built-in
sorted()
function
, you can set the
key
parameter of this function combined with
lambda
to set what specifically you would like to have sorted in your nested dictionary.
Here’s what this is looking like (keeping the list comprehension to make it easier to view):
>>> [sorted(value.items(), key=lambda x:x[1]) for key, value in nested_dict.items()]
[[('A', 1), ('B', 2), ('C', 3)],
[('A', 1), ('B', 2), ('C', 3)],
[('C', 1), ('B', 1), ('A', 1)]]
Beautiful! As you can see, the result is a list of lists where the second element in the tuple (the value of the nested dictionary) is used to determine how this is to be sorted.
Instead of returning a list of values I could further wrap the
sorted()
function
by the
dict()
function to have a list of dicts:
>>> [dict(sorted(value.items(), key=lambda x:x[1])) for key, value in nested_dict.items()]
[{'A': 1, 'B': 2, 'C': 3},
{'A': 1, 'B': 2, 'C': 3},
{'C': 1, 'B': 1, 'A': 1}]
Sorted Dictionary By Value
Now that I’ve been able to demonstrate how to sort the nested dictionary items setting this back to the original dictionary can be done through the original dict comprehension as shown:
>>> {key: dict(sorted(value.items(), key=lambda x:x[1])) for key, value in nested_dict.items()}
{'dict1': {'A': 1, 'B': 2, 'C': 3},
'dict2': {'A': 1, 'B': 2, 'C': 3},
'dict3': {'C': 1, 'B': 1, 'A': 1}}
As you can see from the above result the outcome is achieved where each dictionary from each main property has been sorted by its value.
How would you be able to sort by dictionary key?
Sort Nested Dictionary By Key
By going through this exercise step by step you should be able to see how easily it would be to modify the requirements to sort the nested dictionary by key.
All you would need to change is the tuple element to reference, instead of the second element you would now reference the first element, therefore, instead of
x[1]
it would be
x[0]
in your lambda function, like so:
>>> {key: dict(sorted(value.items(), key=lambda x:x[0])) for key, value in nested_dict.items()}
{'dict1': {'A': 1, 'B': 3, 'C': 3},
'dict2': {'A': 1, 'B': 2, 'C': 3},
'dict3': {'A': 1, 'B': 1, 'C': 1}}
And as you can see from the
dict3
property the keys are now sorted in the nested dictionary.
Sorting Nested Dictionaries By Key Or Value: Summary
By understanding step by step how to sort a dictionary by its key or values you can further refine according to the requirements of your task at hand.
For example, if you had to sort the keys or values in
descending
order you could apply the parameter
reverse=True
to the
sorted()
function.
To sort a nested dictionary with one line of Python code use
{key: dict(sorted(value.items(), key=lambda x:x[0])) for key, value in nested_dict.items()}
where
0
in the
x[0]
lambda expression determines sorting by
key
and
1
sorts by
value
.
You can explore more on how to sort a flat dictionary by key or by value using Python here.