Skip to Content

Sort Dictionary By Key Or Value In Python [Examples, One-Liners, No Imports]

It can be easy to sort a list, whether a list of strings or even a list of dictionaries, but can you sort just a dictionary?

Another handy expression that is very similar to list comprehensions is a dictionary comprehension. It works in a very similar way, and has 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 original 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, such as .items(). But what does this method do and get from the corresponding dictionary?

Let’s explore what this dictionary method does by way of an example:

>>> my_dict = {'a': 3, 'b': 1, 'c': 2}
>>> my_dict.items()
dict_items([('a', 3), ('b', 1), ('c', 2)])

It produces a list of tuples with each tuple containing the key first, followed by the value of that key second.

Knowing that the result is in a list of tuples, you could apply the same techniques 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 Dictionary 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 Dictionary 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}

Sort Nested Dictionaries

While the examples above have been simple key:value pairs, what would happen if keys reference other dictionary values?

For these types of requirements the key parameter in the sorted() function would need to reference a custom function on how to handle individual properties.

One solution could be to check if the value of an item is of a dict data type, and if so to use a recursive function

def multi_dict_sort(d, sort_type=0):
    """
    Sorts a dictionary with multiple sub-dictionaries.
    :param d: dictionary to sort
    :param sort_type: for key sort use 0 [default]; for value sort use 1
    :return: dict
    """
    items_list = [key for (key, value) in d.items() if type(value) is dict]
    for item_key in items_list:
        d[item_key] = multi_dict_sort(d[item_key], sort_type)
    return {key: value for (key, value) in sorted(d.items(), key=lambda x: x[sort_type])}

x = {'c': 1, 'a': { 'f': 20, 'e': 50 }, 'b': { 'r': 10, 'q': { 'z': 9, 'y': 1 } } }
print( multi_dict_sort(x) )

# {'a': {'e': 50, 'f': 20}, 'b': {'q': {'y': 1, 'z': 9}, 'r': 10}, 'c': 1}

As you can see from the basic example used, the original dictionary had an assortment of values for some keys and dictionary values for others, with some dictionaries having another nested dictionary.

The recursive function allows for the iteration of the each value within the dictionary and uses a list comprehension with an if condition to obtain just the keys within the dictionary that have dict data types.

Once a list of items is obtained a simple for loop proceeds through each key and runs the function again with the sub-dictionary.

If there are no sub-dictionaries then the function proceeds to sort all the dictionary items according to the type of sort_type determined: keys is 0 and values is 1.

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.