HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonMinor

Invert dict of sets in Python

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
invertdictpythonsets

Problem

What is the most Pythonic way to take a dict of lists and produce a new dict with the list items as keys and the previous dict's keys as list items.

Here's a visual explanation:

favorite_fruits = {"alice": {"apple", "orange"}, "bob": {"apple"}, "carol": {"orange"}}
people_by_fruit = {"orange": {"carol", "alice"}, "apple": {"bob", "alice"}}


Here's the best I have at the moment:

from collections import defaultdict
favorite_fruits = {"alice": {"apple", "orange"}, "bob": {"apple"}, "carol": {"orange"}}
people_by_fruit = defaultdict(set)
for person, fruit in favorite_fruits.items():
    for fruit in fruit:
        people_by_fruit[fruit].add(person)

Solution

Actually, I do believe you are quite good as you are. The simple inversion listed in this similar question (from comments) does not work when you want to split up the set values of your first dict. You could try something like a dict comprehension with a double for loop, but that doesn't work either as the second time you get a fruit it will overwrite the first one.

The only thing I would like to change in your answer is to use the plural of fruit, fruits, so that you don't do the for fruit in fruit which looks kind of hairy, and has the potential for code breaking as you're overwriting a variable with the same variable. Not good. In other words:

people_by_fruit = defaultdict(set)
for person, fruits in favorite_fruits.items():
    for fruit in fruits:
        people_by_fruit[fruit].add(person)

Code Snippets

people_by_fruit = defaultdict(set)
for person, fruits in favorite_fruits.items():
    for fruit in fruits:
        people_by_fruit[fruit].add(person)

Context

StackExchange Code Review Q#110728, answer score: 5

Revisions (0)

No revisions yet.