Python reverse / invert a mapping

2018-12-31 03:53发布

Given a dictionary like so:

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

How can one invert this map to get:

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

EDITOR NOTE: map changed to my_map to avoid conflicts with the built-in function, map. Some comments may be affected below.

30条回答
心情的温度
2楼-- · 2018-12-31 03:54

If the values aren't unique, and you're a little hardcore:

inv_map = dict(
    (v, [k for (k, xx) in filter(lambda (key, value): value == v, my_map.items())]) 
    for v in set(my_map.values())
)

Especially for a large dict, note that this solution is far less efficient than the answer Python reverse / invert a mapping because it loops over items() multiple times.

查看更多
泪湿衣
3楼-- · 2018-12-31 03:55

This handles non-unique values and retains much of the look of the unique case.

inv_map = {v:[k for k in my_map if my_map[k] == v] for v in my_map.itervalues()}

For Python 3.x, replace itervalues with values. I can't take credit for this... it was suggested by Icon Jack.

查看更多
十年一品温如言
4楼-- · 2018-12-31 03:56

Inverse your dictionary:

dict_ = {"k0":"v0", "k1":"v1", "k2":"v1"}
inversed_dict_ = {val: key for key, val in dict_.items()}

print(inversed_dict_["v1"])
查看更多
十年一品温如言
5楼-- · 2018-12-31 03:57

We may also reverse a dictionary with duplicate keys using defaultdict:

from collections import Counter, defaultdict

def invert_dict(d):
    d_inv = defaultdict(list)
    for k, v in c.items():
        d_inv[v].append(k)
    return d_inv

text = 'aaa bbb ccc ffffd aaa bbb ccc aaa' 
c = Counter(text.split()) # Counter({'aaa': 3, 'bbb': 2, 'ccc': 2, 'ffffd': 1})
dict(invert_dict(c)) # {1: ['ffffd'], 2: ['bbb', 'ccc'], 3: ['aaa']}  

See here:

This technique is simpler and faster than an equivalent technique using dict.setdefault().

查看更多
像晚风撩人
6楼-- · 2018-12-31 03:57

Since dictionaries require one unique key within the dictionary unlike values, we have to append the reversed values into a list of sort to be included within the new specific keys.

def r_maping(dictionary):
    List_z=[]
    Map= {}
    for z, x in dictionary.iteritems(): #iterate through the keys and values
        Map.setdefault(x,List_z).append(z) #Setdefault is the same as dict[key]=default."The method returns the key value available in the dictionary and if given key is not available then it will return provided default value. Afterward, we will append into the default list our new values for the specific key.
    return Map
查看更多
心情的温度
7楼-- · 2018-12-31 03:57

For all kinds of dictionary, no matter if they don't have unique values to use as keys, you can create a list of keys for each value

inv_map = {v: inv_map.get(v, []) + [k] for k,v in my_map.items()}
查看更多
登录 后发表回答