Switching dictionary keys and values in Python

Yesterday a student asked how could he may swap a dictionary so that keys become values and values keys.

One naive solution may be something like that:

new_dict = dict([(value,key) for key,value in old_dict.items()])

However, this solution has a major drawback: keys are guaranteed to be unique, while values may not. Given the fact that old_dict.items() returns a list of dictionary (key,value) elements in an arbitrary order, the last key having a specific value will be the final value in the new_dict. Example:

>>> old_dict = {12:1,76:3,23:1,3:3}
>>> old_dict.items()
dict_items([(76, 3), (3, 3), (12, 1), (23, 1)])
>>> new_dict = dict([(value,key) for key,value in old_dict.items()])
>>> new_dict
{1: 23, 3: 3}

Notice that (3,3) and (23,1) are the (key,value) pairs used to build he new dictionary.

Maybe the intended result is to have a (value,[key1,key2,..]) element for each value. This can be achieved using a for loop like:

for key,value in old_dict.items():
   if value in new_dict:
       new_dict[value].append(key)
   else:
       new_dict[value]=[key]

or by using a comprehension like:

new_dict = dict([(value, [key for key,v in old_dict.items() if v==value]) for value in set(old_dict.values())])

which gives {1: [12, 23], 3: [76, 3]} as result.

The latter example loops through the dictionary N times, where N is the number of distinct values, while the former performs just one loop.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s