Skip to content

Sort Python Dictionary by Value

[

Sorting a Python Dictionary: Values, Keys, and More

by Ian Currie

You’ve got a dictionary, but you’d like to sort the key-value pairs. Perhaps you’ve tried passing a dictionary to the sorted() function but haven’t gotten the results you expected. In this tutorial, you’ll go over everything you need to know if you want to sort dictionaries in Python.

In this tutorial, you’ll:

  • Review how to use the sorted() function
  • Learn how to get dictionary views to iterate over
  • Understand how dictionaries are cast to lists during sorting
  • Learn how to specify a sort key to sort a dictionary by value, key, or nested attribute
  • Review dictionary comprehensions and the dict() constructor to rebuild your dictionaries
  • Consider alternative data structures for your key-value data

Rediscovering Dictionary Order in Python

Before Python 3.6, dictionaries were inherently unordered. A Python dictionary is an implementation of the hash table, which is traditionally an unordered data structure.

As a side effect of the compact dictionary implementation in Python 3.6, dictionaries started to conserve insertion order. From 3.7, that insertion order has been guaranteed.

If you wanted to keep an ordered dictionary as a data structure before Python 3.6, you could use the collections.OrderedDict class. However, since Python 3.7, dictionaries natively preserve insertion order, eliminating the need for OrderedDict in most cases.

Understanding What Sorting A Dictionary Really Means

When you talk about sorting a dictionary, it’s important to clarify what you mean by “sorting.” Since dictionaries are inherently unordered, you can’t really sort a dictionary as is. Instead, you can sort the keys or the values of a dictionary, which gives you the illusion of a sorted dictionary.

Sorting Dictionaries in Python

Using the sorted() Function

To sort a dictionary by its keys or values, you can use the sorted() function. The sorted() function takes an iterable as its argument and returns a new list containing the sorted elements of the iterable.

Here’s an example of sorting a dictionary by its keys:

my_dict = {"apple": 5, "banana": 2, "cherry": 7}
sorted_dict_keys = sorted(my_dict.keys())
print(sorted_dict_keys)

Output:

['apple', 'banana', 'cherry']

And here’s an example of sorting a dictionary by its values:

my_dict = {"apple": 5, "banana": 2, "cherry": 7}
sorted_dict_values = sorted(my_dict.values())
print(sorted_dict_values)

Output:

[2, 5, 7]

Getting Keys, Values, or Both From a Dictionary

If you want to sort a dictionary by its keys or values and also get the corresponding keys or values, you can use dictionary views. Dictionary views provide a dynamic view of the keys, values, or key-value pairs in a dictionary.

To get a dictionary view of the keys, use the keys() method:

my_dict = {"apple": 5, "banana": 2, "cherry": 7}
sorted_dict_keys = sorted(my_dict.keys())
print(sorted_dict_keys)

Output:

['apple', 'banana', 'cherry']

To get a dictionary view of the values, use the values() method:

my_dict = {"apple": 5, "banana": 2, "cherry": 7}
sorted_dict_values = sorted(my_dict.values())
print(sorted_dict_values)

Output:

[2, 5, 7]

To get a dictionary view of the key-value pairs, use the items() method:

my_dict = {"apple": 5, "banana": 2, "cherry": 7}
sorted_dict_items = sorted(my_dict.items())
print(sorted_dict_items)

Output:

[('apple', 5), ('banana', 2), ('cherry', 7)]

Understanding How Python Sorts Tuples

When sorting a dictionary using the sorted() function, Python uses the default comparison rules for tuples. Tuples are compared element by element, starting from the first element. If the first elements are equal, Python moves to the second elements and so on until a difference is found.

Here’s an example to illustrate how Python sorts tuples:

my_tuple1 = (1, 2)
my_tuple2 = (2, 1)
my_tuple3 = (1, 2, 3)
print(my_tuple1 < my_tuple2) # Output: True
print(my_tuple1 < my_tuple3) # Output: True

In the first comparison, (1, 2) is less than (2, 1) because the first element of (1, 2) (1) is less than the first element of (2, 1) (2).

In the second comparison, (1, 2) is less than (1, 2, 3) because both tuples have the same first element, but the second element of (1, 2) (2) is less than the second element of (1, 2, 3) (2).

Using the key Parameter and Lambda Functions

To sort a dictionary by its values in descending order, you can use the key parameter of the sorted() function and a lambda function. A lambda function is a small anonymous function that can be used inline.

Here’s an example:

my_dict = {"apple": 5, "banana": 2, "cherry": 7}
sorted_dict_values_desc = sorted(my_dict.items(), key=lambda x: x[1], reverse=True)
print(sorted_dict_values_desc)

Output:

[('cherry', 7), ('apple', 5), ('banana', 2)]

In this example, the lambda function lambda x: x[1] is used as the key parameter to specify that the sorting should be based on the second element of each key-value pair (the value). The reverse=True parameter is used to sort the dictionary in descending order.

Selecting a Nested Value With a Sort Key

If your dictionary contains nested values, you can use a sort key to select a specific nested value for sorting. A sort key is a lambda function that returns the value you want to use for sorting.

Here’s an example:

my_dict = {"apple": {"quantity": 5}, "banana": {"quantity": 2}, "cherry": {"quantity": 7}}
sorted_dict_nested_value = sorted(my_dict.items(), key=lambda x: x[1]["quantity"])
print(sorted_dict_nested_value)

Output:

[('banana', {'quantity': 2}), ('apple', {'quantity': 5}), ('cherry', {'quantity': 7})]

In this example, the lambda function lambda x: x[1]["quantity"] is used as the sort key to specify that the sorting should be based on the nested value quantity.

Converting Back to a Dictionary

After sorting a dictionary, you might want to convert it back into a dictionary. You can do this using dictionary comprehensions or the dict() constructor.

Here’s an example using dictionary comprehensions:

my_dict = {"apple": 5, "banana": 2, "cherry": 7}
sorted_dict_keys = sorted(my_dict.keys())
sorted_dict = {k: my_dict[k] for k in sorted_dict_keys}
print(sorted_dict)

Output:

{'apple': 5, 'banana': 2, 'cherry': 7}

And here’s an example using the dict() constructor:

my_dict = {"apple": 5, "banana": 2, "cherry": 7}
sorted_dict_keys = sorted(my_dict.keys())
sorted_dict = dict((k, my_dict[k]) for k in sorted_dict_keys)
print(sorted_dict)

Output:

{'apple': 5, 'banana': 2, 'cherry': 7}

Considering Strategic and Performance Issues

When sorting key-value data, there are strategic and performance issues to consider. Sorting a dictionary can introduce additional overhead and might not always be the best solution depending on your use case.

Using Special Getter Functions to Increase Performance and Readability

If you need to sort a dictionary multiple times, you can use special getter functions to increase performance and readability. Getter functions are functions that extract a specific value from an object. By using a getter function as the sort key, you can avoid unnecessary recalculations and improve sorting performance.

Here’s an example using the operator.itemgetter() function as a getter function:

import operator
my_dict = {"apple": 5, "banana": 2, "cherry": 7}
sorted_dict_values = sorted(my_dict.items(), key=operator.itemgetter(1))
print(sorted_dict_values)

Output:

[('banana', 2), ('apple', 5), ('cherry', 7)]

In this example, operator.itemgetter(1) is used as the sort key to specify that the sorting should be based on the second element of each key-value pair (the value).

Measuring Performance When Using itemgetter()

To measure the performance of using the operator.itemgetter() function as a getter function, you can use the timeit module. The timeit module provides a simple way to time small bits of Python code.

Here’s an example measuring the performance of sorting a dictionary by values using operator.itemgetter():

import operator
import timeit
my_dict = {"apple": 5, "banana": 2, "cherry": 7}
getter_sort_time = timeit.timeit(lambda: sorted(my_dict.items(), key=operator.itemgetter(1)), number=100000)
print(f"Sorting time using itemgetter(): {getter_sort_time} seconds")

Output:

Sorting time using itemgetter(): 0.111916735 seconds

In this example, the timeit module is used to time the sorted() function with key=operator.itemgetter(1) for sorting a dictionary by values. The number parameter is set to 100000 to ensure accurate timing.

Judging Whether You Want to Use a Sorted Dictionary

Before sorting a dictionary, it’s important to consider whether a sorted dictionary is really your best option. Sorting a dictionary can introduce additional overhead and might not be necessary depending on your use case.

If you only need to access the minimum or maximum element from a dictionary, you can use the min() and max() functions with a key argument to achieve the same result without sorting the entire dictionary.

Here’s an example:

my_dict = {"apple": 5, "banana": 2, "cherry": 7}
min_value = min(my_dict.items(), key=lambda x: x[1])
max_value = max(my_dict.items(), key=lambda x: x[1])
print(min_value) # Output: ('banana', 2)
print(max_value) # Output: ('cherry', 7)

In this example, the min() and max() functions are used with a lambda function as the key argument to find the minimum and maximum values in the dictionary.

Comparing the Performance of Different Data Structures

If performance is a crucial factor in your application, you might want to consider using alternative data structures for your key-value data. Python offers several built-in and third-party data structures that provide different performance characteristics.

Some alternative data structures for key-value data include:

Choosing the right data structure depends on your specific requirements and use case. Consider the expected workload, the size of your data, and the complexity of your operations when selecting a data structure.

Comparing the Performance of Sorting

If sorting your key-value data is necessary, you might want to compare the performance of different sorting techniques to make an informed decision. The timeit module can be used to measure the performance of different sorting techniques.

Here’s an example comparing the performance of sorting a dictionary by values using different methods:

import timeit
my_dict = {"apple": 5, "banana": 2, "cherry": 7}
method1_sort_time = timeit.timeit(lambda: sorted(my_dict.items(), key=lambda x: x[1]), number=100000)
method2_sort_time = timeit.timeit(lambda: sorted(my_dict.items(), key=lambda x: x[1], reverse=True), number=100000)
method3_sort_time = timeit.timeit(lambda: sorted(my_dict.items(), key=lambda x: -x[1]), number=100000)
print(f"Sorting time using method 1: {method1_sort_time} seconds")
print(f"Sorting time using method 2: {method2_sort_time} seconds")
print(f"Sorting time using method 3: {method3_sort_time} seconds")

Output:

Sorting time using method 1: 0.067912322 seconds
Sorting time using method 2: 0.065828434 seconds
Sorting time using method 3: 0.065133992 seconds

In this example, the timeit module is used to time different sorting methods for sorting a dictionary by values. Method 1 uses the default sorting method, method 2 sorts in descending order, and method 3 negates the values before sorting to achieve the same result.

Comparing the Performance of Lookups

In addition to sorting, you might also need to consider the performance of lookups when working with key-value data. Different data structures have different lookup performance characteristics.

For example, dictionaries provide constant-time average case lookup, which means that the time it takes to find a value in a dictionary does not depend on the size of the dictionary. On the other hand, lists have linear-time average case lookup, which means that the time it takes to find a value in a list increases linearly with the size of the list.

Consider the expected frequency and complexity of your lookup operations when selecting a data structure for your key-value data.

Conclusion

Sorting a dictionary in Python involves sorting the keys or values of the dictionary, as dictionaries themselves are inherently unordered. You can use the sorted() function to sort a dictionary by its keys or values. By using the key parameter and lambda functions, you can specify custom sorting criteria, such as sorting by nested values. After sorting a dictionary, you can use dictionary comprehensions or the dict() constructor to convert it back into a dictionary.

Before sorting a dictionary, consider whether a sorted dictionary is really necessary for your use case. Sorting a dictionary can introduce additional overhead and might not be the best solution depending on your operations and performance requirements. Consider using alternative data structures or specific lookup operations if sorting is not essential.

With the knowledge and techniques presented in this tutorial, you’ll be able to effectively sort dictionaries in Python and make informed decisions about when and how to sort your key-value data.