Question

For example, I call this function by passing a dictionary as parameter:

>>> inv_map({'a':1, 'b':2, 'c':3, 'd':2})
{1: ['a'], 2: ['b', 'd'], 3: ['c']}
>>> inv_map({'a':3, 'b':3, 'c':3})
{3: ['a', 'c', 'b']}
>>> inv_map({'a':2, 'b':1, 'c':2, 'd':1})
{1: ['b', 'd'], 2: ['a', 'c']}

If

map = { 'a': 1, 'b':2 }

I can only invert this map to get:

inv_map = { 1: 'a', 2: 'b' }

by using this

dict((v,k) for k, v in map.iteritems())

Anyone knows how to do that for my case?

Was it helpful?

Solution

You can use a defaultdict with list:

>>> from collections import defaultdict
>>> m = {'a': 2, 'b': 1, 'c': 2, 'd': 1}
>>> dd = defaultdict(list)
>>> for k, v in m.iteritems():
...     dd[v].append(k)
... 
>>> dict(dd)
{1: ['b', 'd'], 2: ['a', 'c']}

If you don't care if you have an dict or defaultdict, you can omit the last step und use the defaultdict directly.

OTHER TIPS

You can probably use defaultdict or setdefault here.

def invertDictionary(orig_dict):
    result = {} # or change to defaultdict(list)
    for k, v in orig_dict.iteritems():
        result.setdefault(v, []).append(k)

EDIT In python 2.7:

from itertools import groupby
def inv_map(d):
    return {k : [i[0] for i in list(v)] for k, v in groupby(d.items(),lambda x:x[1])}

print inv_map({'a':1, 'b':2, 'c':3, 'd':2})
print inv_map({'a':3, 'b':3, 'c':3})
print inv_map({'a':2, 'b':1, 'c':2, 'd':1})

Output:

{1: ['a'], 2: ['b', 'd'], 3: ['c']}
{3: ['a', 'c', 'b']}
{1: ['b', 'd'], 2: ['a', 'c']}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top