Dictionaries map keys to values. Looking up a value is as simple as typing: mydict[key]. But what if you want to look up a key? The following one liner returns a new dictionary with the keys and values swapped:
1 2 3 4 5 6 | # Invert a dictionary
mydict = {"Apple": "red", "Banana": "yellow", "Carrot": "orange"}
inverted_dict = dict([[v,k] for k,v in mydict.items()])
print inverted_dict["red"]
|
Sometimes the keys and values in a dictionary have equal importance as references. Inverting a dictionary allows you to reverse the mapping and use a value to look up a key. NOTE: This only works if there are no duplicate values in the dictionary. If there are common values only the last key will be preserved once swapped. One way to deal with duplicate values is to turn all keys with a common value into a list when you invert the dictionary. I haven't found a shortcut for that method yet.
My own solution. DictInvert = lambda d: dict(zip(d.values(), d.keys()))
Think iterator! Both of the solutions could benefit from using the iterator forms: iteritems, iterkeys, itervalues, izip.
Iterator and common values. Here's an iterator version that does turn all keys with a common value into a list when you invert the dictionary.
E.g.
{88: ['c'], 55: ['a', 'b']}
keys() and values() will always be in order. Will the values of keys() and values() always be in the same order?
That is, your little lambda won't reorder the relationship between value and key?
Ciao!
Keys must be hashable. Just a small note: the keys to a dictionary must be hashable, so in the above, this must be enforced. For types that can be converted to strings, this can be the best method, but there can clearly be some loss of functionality.
Generator expressions were introduced in Python 2.4, so the intermediate list is no longer required:
Jason's comment manages duplicate values. It may be simpler to disallow them:
My comment missed out Raymond's advice, it should have been:
I think this his is the shortest one:
... this is not the shortest one, but maybe the most crpytic :-)
If you need to maintain the inverse mapping across many updates and changes, then these one-shot one-liners must be re-computed many times. To cope with that situation, I just added Recipe 576968 with a python dict subclass.