Skip to content

Effortlessly 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

Along the way, you’ll also use the timeit module to time your code and get tangible results for comparing the different methods of sorting key-value data. You’ll also consider whether a sorted dictionary is really your best option, as it’s not a particularly common pattern.

To get the most out of this tutorial, you should know about dictionaries, lists, tuples, and functions. With that knowledge, you’ll be able to sort dictionaries by the end of this tutorial. Some exposure to lambda functions, such as lambda functions, will also come in handy but isn’t a requirement.

First up, you’ll learn some foundational knowledge before trying to sort a dictionary in Python.

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 would have had to use OrderedDict from the collections module.

Understanding What Sorting A Dictionary Really Means

Sorting a dictionary might sound like a simple task at first. You might think that the sorted() function should be able to handle it. However, dictionaries in Python are inherently unordered, which means the order in which the key-value pairs are stored is not preserved.

When you sort a dictionary, you’re actually sorting the keys and then using those sorted keys to access the corresponding values. The result is a list of key-value pairs sorted by the keys.

Sorting Dictionaries in Python

Now that you understand the basics, let’s dive into the different methods you can use to sort dictionaries in Python.

Using the sorted() Function

The sorted() function allows you to sort any iterable by specifying a key function to determine the sort order. To sort a dictionary, you can pass its keys to the sorted() function, which will return a sorted list of keys.

# Sample dictionary
my_dict = {'B': 3, 'A': 1, 'D': 4, 'C': 2}
# Sort the dictionary by keys
sorted_keys = sorted(my_dict.keys())
# Print the sorted keys
print(sorted_keys)

Output:

['A', 'B', 'C', 'D']

Getting Keys, Values, or Both From a Dictionary

If you want to sort the dictionary by values, you can use the key parameter of the sorted() function and provide a lambda function that returns the values of each key.

# Sort the dictionary by values
sorted_values = sorted(my_dict.keys(), key=lambda x: my_dict[x])
# Print the sorted values
print(sorted_values)

Output:

['A', 'C', 'B', 'D']

If you want to sort the dictionary by both keys and values, you can use the items() method of the dictionary to get a list of key-value pairs and then sort that list using the key parameter.

# Sort the dictionary by both keys and values
sorted_items = sorted(my_dict.items(), key=lambda x: (x[0], x[1]))
# Print the sorted items
print(sorted_items)

Output:

[('A', 1), ('B', 3), ('C', 2), ('D', 4)]

Understanding How Python Sorts Tuples

When you sort a list of tuples using the sorted() function, Python uses a built-in comparison algorithm to determine the sort order. The algorithm compares the elements of each tuple in the list and sorts them based on the result of the comparison.

By default, Python compares the elements of each tuple in lexicographic order, meaning it compares the first element of each tuple, then the second element if the first elements are equal, and continues until it finds a difference or reaches the end of the tuple.

Using the key Parameter and Lambda Functions

If you want to specify a custom sort order for the values of each key, you can use the key parameter of the sorted() function and provide a lambda function.

The lambda function takes an element from the iterable and returns a value that will be used for the sort comparison. In the case of sorting dictionaries, you can use the lambda function to extract the values of each key and provide them for the sort comparison.

# Sort the dictionary by values in descending order
sorted_values_desc = sorted(my_dict.keys(), key=lambda x: my_dict[x], reverse=True)
# Print the sorted values in descending order
print(sorted_values_desc)

Output:

['D', 'B', 'C', 'A']

Selecting a Nested Value With a Sort Key

If your dictionary contains nested values, you can use the key parameter and a lambda function to select a specific nested value as the sort key. This allows you to sort the dictionary based on that nested value.

# Sample dictionary with nested values
nested_dict = {'B': {'value': 3}, 'A': {'value': 1}, 'D': {'value': 4}, 'C': {'value': 2}}
# Sort the dictionary by the nested value
sorted_nested_values = sorted(nested_dict.keys(), key=lambda x: nested_dict[x]['value'])
# Print the sorted nested values
print(sorted_nested_values)

Output:

['A', 'C', 'B', 'D']

Converting Back to a Dictionary

After sorting the dictionary, you might want to convert it back to a dictionary data structure. To do this, you can use a dictionary comprehension or the dict() constructor.

# Convert the sorted keys and values back to a dictionary
sorted_dict_comp = {key: my_dict[key] for key in sorted_keys}
sorted_dict_constructor = dict(sorted_items)
# Print the sorted dictionary
print(sorted_dict_comp)
print(sorted_dict_constructor)

Output:

{'A': 1, 'B': 3, 'C': 2, 'D': 4}
{'A': 1, 'B': 3, 'C': 2, 'D': 4}

Considering Strategic and Performance Issues

When working with sorted dictionaries, there are some strategic and performance considerations to keep in mind.

Using Special Getter Functions to Increase Performance and Readability

If you need to sort large dictionaries or dictionaries with complex nested values, using the itemgetter() function from the operator module can provide a performance boost. It provides a faster alternative to the lambda function when sorting dictionaries.

from operator import itemgetter
# Sort the dictionary using itemgetter
sorted_items_getter = sorted(my_dict.items(), key=itemgetter(1))
# Print the sorted items using itemgetter
print(sorted_items_getter)

Output:

[('A', 1), ('C', 2), ('B', 3), ('D', 4)]

Measuring Performance When Using itemgetter()

To measure the performance of different methods of sorting dictionaries, you can use the timeit module. This module allows you to time your code and get tangible results for comparing the different methods.

import timeit
# Time the sorting using itemgetter
time_itemgetter = timeit.timeit(
stmt="sorted(my_dict.items(), key=itemgetter(1))",
setup="from operator import itemgetter; my_dict = {'B': 3, 'A': 1, 'D': 4, 'C': 2}",
number=1000000
)
# Print the time taken
print(f"Time taken using itemgetter: {time_itemgetter} seconds")

Output:

Time taken using itemgetter: 2.4182425639999984 seconds

Judging Whether You Want to Use a Sorted Dictionary

While sorting dictionaries can be useful in some cases, it’s important to consider whether a sorted dictionary is really your best option. Sorting a dictionary requires additional time and memory compared to an unordered dictionary.

If you frequently need to access the dictionary in a specific order, it might be worth considering alternative data structures like lists or arrays that are specifically designed for ordered data.

Comparing the Performance of Different Data Structures

To compare the performance of different data structures for storing key-value data, you can use the timeit module again and time the different methods.

# Time the sorting with different data structures
time_sorted_dict = timeit.timeit(
stmt="sorted(my_dict.items(), key=itemgetter(1))",
setup="from operator import itemgetter; my_dict = {'B': 3, 'A': 1, 'D': 4, 'C': 2}",
number=1000000
)
time_list_of_tuples = timeit.timeit(
stmt="sorted([(k, v) for k, v in my_dict.items()], key=itemgetter(1))",
setup="from operator import itemgetter; my_dict = {'B': 3, 'A': 1, 'D': 4, 'C': 2}",
number=1000000
)
# Print the times taken
print(f"Time taken using sorted dictionary: {time_sorted_dict} seconds")
print(f"Time taken using list of tuples: {time_list_of_tuples} seconds")

Output:

Time taken using sorted dictionary: 2.389120605000001 seconds
Time taken using list of tuples: 3.1121981570000007 seconds

Comparing the Performance of Sorting

You can also compare the performance of sorting different data structures by measuring the time taken for each method.

# Time the sorting of different data structures
time_dict_sort = timeit.timeit(
stmt="dict(sorted(my_dict.items(), key=itemgetter(1)))",
setup="from operator import itemgetter; my_dict = {'B': 3, 'A': 1, 'D': 4, 'C': 2}",
number=1000000
)
time_list_dict = timeit.timeit(
stmt="dict(sorted([(k, v) for k, v in my_dict.items()], key=itemgetter(1)))",
setup="from operator import itemgetter; my_dict = {'B': 3, 'A': 1, 'D': 4, 'C': 2}",
number=1000000
)
# Print the times taken
print(f"Time taken sorting dictionary: {time_dict_sort} seconds")
print(f"Time taken sorting list of tuples: {time_list_dict} seconds")

Output:

Time taken sorting dictionary: 3.2150905160000007 seconds
Time taken sorting list of tuples: 3.5558284280000007 seconds

Comparing the Performance of Lookups

Lastly, you can compare the performance of lookups in different data structures by timing the access to a specific key.

# Time the access to a specific key in different data structures
time_dict_lookup = timeit.timeit(
stmt="my_dict['C']",
setup="my_dict = {'B': 3, 'A': 1, 'D': 4, 'C': 2}",
number=1000000
)
time_list_lookup = timeit.timeit(
stmt="[v for k, v in my_list if k == 'C'][0]",
setup="my_list = [('B', 3), ('A', 1), ('D', 4), ('C', 2)]",
number=1000000
)
# Print the times taken
print(f"Time taken for dictionary lookup: {time_dict_lookup} seconds")
print(f"Time taken for list lookup: {time_list_lookup} seconds")

Output:

Time taken for dictionary lookup: 0.06351291299999996 seconds
Time taken for list lookup: 0.3287353799999999 seconds

Conclusion

In this tutorial, you learned how to sort dictionaries in Python using various methods. You explored the use of the sorted() function, lambda functions, and the itemgetter() function to sort dictionaries based on keys and values. You also considered performance issues and alternative data structures for storing key-value data.

Remember that sorting dictionaries is not a common pattern and should only be done when necessary. Consider the trade-offs in terms of time and memory before deciding to sort a dictionary. With the knowledge gained from this tutorial, you can effectively sort dictionaries in Python and optimize your code when dealing with key-value data.