DEV Community

Discussion on: How to Invert a Dictionary in Python: Comprehensions, Defaultdict, and More

Collapse
 
nielsgl profile image
Niels van Galen Last • Edited

Inverting the original dict with non-unique values can be done cleaner (without the explicit two line for loop and IMO easier to read) using a defaultdict:

>>> from collections import defaultdict
>>> # Original dict
>>> my_dict = {
  'Izuku Midoriya': 'One for All',
  'Katsuki Bakugo': 'Explosion',
  'All Might': 'One for All',
  'Ochaco Uraraka': 'Zero Gravity'
}
>>> my_dict_inverted = defaultdict(list)

>>> [my_dict_inverted[v].append(k) for k, v in my_dict.items()]

>>> my_dict_inverted
defaultdict(<class 'list'>, {'One for All': ['Izuku Midoriya', 'All Might'],
   'Explosion': ['Katsuki Bakugo'], 'Zero Gravity': ['Ochaco Uraraka']})

Or to make it more intuitive denote the comprehension using a dict since that is what we are applying the operation to:

>>> my_dict_inverted = defaultdict(list)

>>> {my_dict_inverted[v].append(k) for k, v in my_dict.items()}

>>> my_dict_inverted
defaultdict(<class 'list'>, {'One for All': ['Izuku Midoriya', 'All Might'],
   'Explosion': ['Katsuki Bakugo'], 'Zero Gravity': ['Ochaco Uraraka']})
Collapse
 
renegadecoder94 profile image
Jeremy Grifski • Edited

Great addition! I would prefer to maintain the dict type and leave out any extraneous imports, but this gets the job done and is probably less error prone.

Mind if I add it to the list?

Collapse
 
nielsgl profile image
Niels van Galen Last

Go ahead :)

It's part of the standard library and it's still a dict so you can use any it like a normal dict, e.g. my_dict_inverted['One for All'] as well as all methods from a normal dict like keys(), values() and items().

Thread Thread
 
renegadecoder94 profile image
Jeremy Grifski

Hi again! I'm in the process of updating this article, and I just realized that this answer has a minor problem. We're using a dictionary comprehension in a bad way. We're updating some external dictionary while the comprehension will also generate a dictionary (in this case, {None}). I believe that's considered bad practice, so I've added a note in the original article.