How to Invert a Dictionary in Python

How to Invert a Dictionary in Python Featured Image

Welcome to the start of the Python Bytes series. In this series, I’m putting together several articles for small Python problems that can be solved in a few lines of code. This series is inspired by the everyday Google searches I make to solve my own problems at work. To get started, I’ve decided to kick off the series by writing an article on how to invert a dictionary.

Table of Contents

Problem Introduction

Recently, I was working on a Python project where I needed to invert a dictionary. Ultimately, I wanted to be able to do the following:

my_dict = {'a': 'fire', 'b': 'ice', 'c': 'fire', d: 'water'}
my_inverted_dict = {'fire': ['a', 'c'], 'ice': ['b'], 'water': ['d']}

In this scenario, the dictionary had non-unique values, so flipping the dictionary would have resulted in a loss of keys. Instead, I wanted to accumulate a list of keys for each non-unique value while performing the inversion. As it turns out, this is pretty easy to do.

Solutions

If we want to invert a dictionary, we have several options. From using a comprehension to using a loop, we’ll take a look at all the practical solutions.

Invert a Dictionary with a Comprehension

In Python 2.7 and above, we can use a dictionary comprehension to invert a dictionary:

my_inverted_dict = {value: key for key, value in my_dict.items()}

If we read into this method though, we’ll notice a problem. We risk losing keys from the original dictionary. For example, here’s the result of inverting our example dictionary:

my_inverted_dictionary = {'fire': 'c', 'ice': 'b', 'water': 'd'}

As we can see, we lose one of our keys. So, there has to be a better way to invert a dictionary.

Invert a Dictionary with a For Loop

Another way to invert a dictionary is to use a for loop. This allows us to iterate over the set of mappings and properly build the new mappings by hand. Take a look:

my_inverted_dict = dict()
for key, value in my_dict.items():
    my_inverted_dict.setdefault(value, list()).append(key)

With this method, we can invert a dictionary while preserving all of our original keys. Let’s take a look at what would happen if we ran this code snippet:

my_inverted_dict = {'fire': ['a', 'c'], 'ice': ['b'], 'water': ['d']}

Great! We have exactly what we need, but what happens if we want to return this dictionary to its original form?

Revert the Inversion

In the basic case where all keys and values are unique, we can revert a dictionary back to its original mapping using the same dictionary comprehension we’ve already covered:

my_dict = {value: key for key, value in my_inverted_dict.items()}

Unfortunately, this doesn’t work out with a dictionary that maps keys to lists. That’s because lists in Python are unhashable types. In other words, Python doesn’t allow lists to be keys in dictionaries because lists are not immutable.

Fortunately, it’s easier to revert our dictionary than it was to invert it in the first place. We can simply use the following dictionary comprehension:

my_dict = {value: key for key in my_inverted_dict for value in my_map[key]}

As we can see, we make a new key-value pair for every single value in each list using this double loop structure.

A Little Recap

Using the three methods above, we can invert just about any dictionary.

# Use to invert dictionaries that have unique values
my_inverted_dict = {value: key for key, value in my_dict.items()}

# Use to invert dictionaries that have non-unique values
my_inverted_dict = dict()
    for key, value in my_dict.items():
        my_inverted_dict.setdefault(value, list()).append(key)

# Use to invert dictionaries that have lists of values
my_dict = {value: key for key in my_inverted_dict for value in my_map[key]}

Just about every other type of dictionary transformation is out of the scope of this tutorial. However, if you have any specific questions, consider picking up The Renegade Coder as your personal tutor and mentor.

Series NavigationHow to Sum Elements of Two Lists in Python →
Advertisements

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.