Sorting a Python Dictionary for Fun & Profit

sorted dictionary python overcoded

The Python dictionary is a powerful data structure of key-value pairs indexed by a non-mutable data type. They are inherently unordered though will preserve the order by which items are added. There is no way to sort a python dictionary directly, however, and one must get a little creative.

Fortunately, one can sort a Python dictionary by converting it to a sortable type such as a list. This involves an intermediary step, or a bold one-liner, but is relatively straightforward. I’ll walk you through some basic gotchas, considerations, and notable options. For those here from Google for a quick answer, check out the TL;DR below:

TL;DR – Use the built-in sorted function with a lambda expression as the key.

# Create a dictionary with randomly ordered keys
d = {5: 'f', 3: 'd', 0: 'a', 2: 'c', 6: 'g', 1: 'b'}

# Sort by converting to list using lambda
d = sorted(d.items(), key=lambda x: x[0])

>>> [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (5, 'f'), (6, 'g')]

# Covert back to a dictionary (if needed)
d = {k: v for k, v in d}

>>> {0: 'a', 1: 'b', 2: 'c', 3: 'd', 5: 'f', 6: 'g'}

Quick Introduction

The Python dictionary is a data structure much like the traditional hash table. It pairs a collection of immutable objects such as an integer, string, or float with paired values that can be mutable or even collections of values.

Python dictionaries are efficient and come packed with tons of useful built-in methods to help with common tasks. Dictionaries are a bit like enums in other languages like Java but have some notable differences.

Sorting A Python Dictionary

Much like the initial TL;DR example, we’re going to start by creating a randomly ordered dictionary. With that, we’ll be able to look at some approaches that work—and some that don’t. Before we dive in, I’ll take a moment and be that guy by advising you to read the official Python dictionary documentation. It does well to lay out many of the methods made available by the Python dictionary structure that we won’t cover here.

# Create a randomly-ordered dictionary
d = {5: 'f', 3: 'd', 0: 'a', 2: 'c', 6: 'g', 1: 'b'}

# Sort the dictionary
sorted(d)

>>> [0, 1, 2, 3, 5, 6]

Whoa! That almost looks like it worked. In this scenario, Python represents dictionaries as keys since (version number citation needed.) Also worth noting is that since PEP448 one can use unpacking directives to produce a list as such:  l = [*d] which would result in a list, though not sorted: [5, 3, 0, 2, 6, 1]. Just some fun facts. Let’s see what that looks like:

Sorting with Comprehensions

Python list comprehension is one of the reasons I fell in love with this programming language. It lets one achieve an impressive workload using one-line logic in a highly optimized fashion. For me, it wasn’t immediately clear that Python also accommodated dictionary comprehension out-of-the-box. It does, and we’ll showcase how it can be used to sort dictionaries in Python also!

# Create a randomly-ordered dictionary
d = {5: 'f', 3: 'd', 0: 'a', 2: 'c', 6: 'g', 1: 'b'}

# Sort using dictionary comprehension
d = {k: v for k, v in sorted(d.items())}

>>> {0: 'a', 1: 'b', 2: 'c', 3: 'd', 5: 'f', 6: 'g'}

Here we’ve not only sorted the dictionary by converting it into a list via the sorted(d.items()) approach but we’ve also converted it back to a dictionary. All in one line! Note: we technically converted it into an intermediary generator object, not a list.

This is looking pretty sweet, but let’s take things a step further and introduce a custom key by which our dictionary will be sorted. For example, let’s say we wanted the dictionary sorted by absolute value from the average value of keys.

Let’s see if we can get a one-liner that is up to the task! For this, I’ll use a slightly longer set of values referencing the ASCII lowercase letters made available via the string module:

# Create a randomly-ordered dictionary
alpha = {k: v for k, v in zip(range(len(string.ascii_lowercase)), list(string.ascii_lowercase))}

>>> {0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f', 6: 'g', 7: 'h', 8: 'i', 9: 'j', 10: 'k', 11: 'l', 12: 'm', 13: 'n', 14: 'o', 15: 'p', 16: 'q', 17: 'r', 18: 's', 19: 't', 20: 'u', 21: 'v', 22: 'w', 23: 'x', 24: 'y', 25: 'z'}

# Order by distance from an calculated value
s = {k: v for k, v in sorted(alpha .items(), key=lambda x: abs(sum(alpha) / len(alpha) - x[0]))}

>>> {12: 'm', 13: 'n', 11: 'l', 14: 'o', 10: 'k', 15: 'p', 9: 'j', 16: 'q', 8: 'i', 17: 'r', 7: 'h', 18: 's', 6: 'g', 19: 't', 5: 'f', 20: 'u', 4: 'e', 21: 'v', 3: 'd', 22: 'w', 2: 'c', 23: 'x', 1: 'b', 24: 'y', 0: 'a', 25: 'z'}

As you can see, the combination of the key argument, a Python lambda function, and dictionary comprehension can do a lot of work. In this case, I’ve sorted a dictionary of the alphabet by proximity to the average position. Why do you ask? Because Python makes it so easy!

Note: Python’s OrderedDict class from the collections module was an often-used alternative to dict objects since it preserved insertion order. Since 3.7 the standard dict object has provided this functionality and has replaced the need for OrderedDict in many cases. OrderedDict still has some performance benefits in some cases and shouldn’t be discounted entirely in my opinion.

Gotchas

Python dictionaries can use a tuple as a key — but that tuple cannot contain a mutable object. For example, tuples are themselves immutable but may contain a structure like a list or an object.

Final Thoughts

Python’s dictionary structure is an incredible tool for hash-mapping and I use them all the time. I use them commonly when I’m storing credentials locally or in the cloud, working with collections where query times are more important than order, and especially when serializing data. Translating between Python dictionaries and JSON-formatted strings is phenomenally easy (here’s looking at you Java.)

Even when the use-case for dictionaries is strong, I find a need to get a sorted version of a collection or, at the very least, derive some value from the sorted order of keys. Using the methods outlined in this article I find that tasks can be accomplished effectively—often in a one-liner. I hope this article has been helpful and urge everyone to recognize we’ve only covered a fraction of the use cases, implications of use, and methods of the Python dictionary data type. There is much more to know about them!

alpharithms discord banner 1
Zαck West
Entrepreneur, programmer, designer, and lifelong learner. Can be found taking notes from Mother Nature when not hammering away at the keyboard.