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 04:07

Fast functional solution for non-bijective maps (values not unique):

from itertools import imap, groupby

def fst(s):
    return s[0]

def snd(s):
    return s[1]

def inverseDict(d):
    """
    input d: a -> b
    output : b -> set(a)
    """
    return {
        v : set(imap(fst, kv_iter))
        for (v, kv_iter) in groupby(
            sorted(d.iteritems(),
                   key=snd),
            key=snd
        )
    }

In theory this should be faster than adding to the set (or appending to the list) one by one like in the imperative solution.

Unfortunately the values have to be sortable, the sorting is required by groupby.

查看更多
零度萤火
3楼-- · 2018-12-31 04:08

Try this:

inv_map = dict(zip(my_map.values(), my_map.keys()))

(Note that the Python docs on dictionary views explicitly guarantee that .keys() and .values() have their elements in the same order, which allows the approach above to work.)

Alternatively:

inv_map = dict((my_map[k], k) for k in my_map)

or using python 3.0's dict comprehensions

inv_map = {my_map[k] : k for k in my_map}
查看更多
只靠听说
4楼-- · 2018-12-31 04:08

Function is symmetric for values of type list; Tuples are coverted to lists when performing reverse_dict(reverse_dict(dictionary))

def reverse_dict(dictionary):
    reverse_dict = {}
    for key, value in dictionary.iteritems():
        if not isinstance(value, (list, tuple)):
            value = [value]
        for val in value:
            reverse_dict[val] = reverse_dict.get(val, [])
            reverse_dict[val].append(key)
    for key, value in reverse_dict.iteritems():
        if len(value) == 1:
            reverse_dict[key] = value[0]
    return reverse_dict
查看更多
明月照影归
5楼-- · 2018-12-31 04:09

Another, more functional, way:

my_map = { 'a': 1, 'b':2 }
dict(map(reversed, my_map.items()))
查看更多
裙下三千臣
6楼-- · 2018-12-31 04:10

if the items are not unique try this:

     dict={}
     dict1={}
     num=int(raw_input(" how many numbers in dict?--> "))
     for i in range (0,num):
         key=raw_input(" enter key --> ")
         value=raw_input("enter value --> ")
         dict[key]=value
     keys=dict.keys()
     values=dict.values()
     for b in range (0,num):
         keys[b],values[b]=values[b],keys[b]
         dict1[keys[b]]=values[b]
     print keys
     print values
     print dict1
查看更多
不流泪的眼
7楼-- · 2018-12-31 04:13

For Python 2.7.x

inv_map = {v: k for k, v in my_map.iteritems()}

For Python 3+:

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