It can be easy to sort a list , whether a list of strings or even a list of dictionaries , but can you sort a dictionary?
One way to sort a dictionary by the values of each
key : value
pair in Python is to use a
dictionary comprehension
.
Dictionary comprehensions are very similar to list comprehensions and have the following schema:
new_dict = { key: value for (key, value) in original_dict.items()}
The first expression within the dictionary comprehension, the
key: value
portion, is the basic structure for setting any key and value pair within a dictionary. The second expression is familiar as the
one-liner for loop
, and within this statement we have a tuple representing the key and value returned from the dictionary’s
.items()
method.
What Does
dict.items()
Do?
Just as list data types have methods, like
.append()
,
dictionary data types in Python
also have methods, and of these is
.items()
. The
items
method returns a
dict_items
data type which appears as a list of tuples.
Here’s what this looks like by way of an example:
>>> my_dict = {'a': 3, 'b': 1, 'c': 2}
>>> my_dict.items()
dict_items([('a', 3), ('b', 1), ('c', 2)])
>>> e = my_dict.items()
>>> type(e)
<class 'dict_items'>
As you can see from the above example where the
.items()
method is run on a dictionary data type, the result is a list of tuples known as a
dict_items
.
Within the list is a tuple containing the key as the first element and the value assigned to that key being the value.
Knowing that the result of the
.items()
method produces a list of tuples, you could apply the
same techniques used when sorting a list
. So if the aim of this example was to sort the dictionary by their values, you could wrap the
.items()
method result in the
sorted()
function and point to the second tuple as being the means of what to sort.
Let’s try it:
>>> my_dict = {'a': 3, 'b': 1, 'c': 2}
>>> sorted(my_dict.items(), key=lambda x: x[1])
[('b', 1), ('c', 2), ('a', 3)]
As shown above, the sort produces a list of tuples with the same structure as the list of tuples received with the returned value from the
.items()
method.
If the requirement was to sort by order of the key you would just change one value in the example above:
>>> my_dict = {'a': 3, 'c': 2, 'b': 1}
>>> sorted(my_dict.items(), key=lambda x: x[0])
[('a', 3), ('b', 1), ('c', 2)]
Besides making a slight change to the original dictionary to demonstrate the point, the only change in the second line is the reference to the first element in the tuple: instead of
lambda x:x[1]
which refers to the value in the dictionary, now the
key
parameter uses
lambda x:x[
0
]
which refers to the
keys
in the original dictionary.
Sort Dict By Value
Combining what has been discovered above with sorting dictionary items into a list of tuples, and what a dictionary comprehension is you should be able to combine both features to perform the sort and return a dictionary of sorted values.
Here’s an example demonstrating this:
>>> my_dict = {'a': 3, 'b': 1, 'c': 2}
>>> {key: value for (key, value) in sorted(my_dict.items(), key=lambda x: x[1])}
{'b': 1, 'c': 2, 'a': 3}
The result as shown above is a new dictionary with the value of each key item being in order.
If the requirement was for the values to be in descending order , you could use either method below:
>>> my_dict = {'a': 3, 'b': 1, 'c': 2}
>>> {key: value for (key, value) in sorted(my_dict.items(), key=lambda x: -x[1])}
{'a': 3, 'c': 2, 'b': 1}
>>> my_dict = {'a': 3, 'b': 1, 'c': 2}
>>> {key: value for (key, value) in sorted(my_dict.items(), key=lambda x: x[1], reverse=True)}
{'a': 3, 'c': 2, 'b': 1}
Notice in the first example, a negative sign was placed in front of the
x[1]
value:
this can only be done when dealing with numeric values
, whereas with the second example, the parameter
reverse
was used and this can be done with numbers and strings.
Sort Dict By Key
Sorting a dictionary by its key value would work in the same way as sorting by value (above), with the only differentiation being the reference used in the
lambda
function for the
key
parameter.
Here’s an example demonstrating a sort of a dictionary by key:
>>> my_dict = {'c': 1, 'a': 3, 'b': 2}
>>> {key: value for (key, value) in sorted(my_dict.items(), key=lambda x: x[0])}
{'a': 3, 'b': 2, 'c': 1}
As the result shows above our original dictionary have created a new dictionary with the keys in alphabetical order.
Again, if the requirements are to reverse the order of the keys then there are two possible means available, however, as stressed above, if the value from the tuple is numeric a negative sign can be placed, but if it’s a string then this would not work.
Here’s what would happen if both reversal techniques were used to perform the sort on the keys:
>>> my_dict = {'c': 1, 'a': 3, 'b': 2}
>>> {key: value for (key, value) in sorted(my_dict.items(), key=lambda x: -x[0])}
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "<input>", line 1, in <lambda>
TypeError: bad operand type for unary -: 'str'
>>> my_dict = {'c': 1, 'a': 3, 'b': 2}
>>> {key: value for (key, value) in sorted(my_dict.items(), key=lambda x: x[0], reverse=True)}
{'c': 1, 'b': 2, 'a': 3}
Notice with the first example because the keys are of a string data type this causes issues when placing a negative sign in front, however, the second example where the
reverse
parameter is used does not have any issues.
(If the key is just one letter, as the first example showed, you could use the
ord()
function
by converting the character into an ordinal Unicode number, here’s a quick demonstration of how that would work. However, this method would only work when the key length is one, would not work if the keys have lengths greater than one)
>>> my_dict = {'c': 1, 'a': 3, 'b': 2}
>>> {key: value for (key, value) in sorted(my_dict.items(), key=lambda x: -ord(x[0]))}
{'c': 1, 'b': 2, 'a': 3}
Summary
Sorting a dictionary by keys and/or values can easily be done in one simple line in Python where a dictionary comprehension is used. Depending upon the type of sort required (i.e. keys or values) determines which value to use in the lambda function.
The flexibility and power of recursive functions permits the use of being able to sort dictionaries even if a dictionary contains multiple sub-dictionaries.