给定一本这样的字典:

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

如何将此映射颠倒得到:

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

当前回答

如果my_map中的值不是唯一的:,我遇到了一个问题,其中不仅值不是唯一的,而且它们是一个列表,列表中的每一项都由三个元素组成:字符串值、数字和另一个数字。

例子:

Mymap ['key1']给你:

[('xyz', 1, 2),
 ('abc', 5, 4)]

我想只切换字符串值与键,保持两个数字元素在同一位置。你只需要另一个嵌套的for循环:

inv_map = {}
for k, v in my_map.items():
    for x in v:
        # with x[1:3] same as x[1], x[2]:
        inv_map[x[0]] = inv_map.get(x[0], []) + [k, x[1:3]]

例子:

Inv_map ['abc']现在给你:

[('key1', 1, 2),
 ('key1', 5, 4)]

其他回答

另一种更实用的方法是:

my_map = { 'a': 1, 'b':2 }
dict(map(reversed, my_map.items()))

不是完全不同的东西,只是从食谱中重写了一点。它通过保留setdefault方法进一步优化,而不是每次通过实例获取它:

def inverse(mapping):
    '''
    A function to inverse mapping, collecting keys with simillar values
    in list. Careful to retain original type and to be fast.
    >> d = dict(a=1, b=2, c=1, d=3, e=2, f=1, g=5, h=2)
    >> inverse(d)
    {1: ['f', 'c', 'a'], 2: ['h', 'b', 'e'], 3: ['d'], 5: ['g']}
    '''
    res = {}
    setdef = res.setdefault
    for key, value in mapping.items():
        setdef(value, []).append(key)
    return res if mapping.__class__==dict else mapping.__class__(res)

设计为在CPython 3下运行。X表示2。用mapping.iteritems()替换mapping.items()

在我的机器上运行得比这里的其他例子快一些

除了上面建议的其他函数,如果你喜欢lambdas:

invert = lambda mydict: {v:k for k, v in mydict.items()}

或者,你也可以这样做:

invert = lambda mydict: dict( zip(mydict.values(), mydict.keys()) )

我知道这个问题已经有很多很好的答案,但我想分享这个非常简洁的解决方案,它也照顾到了重复值:

def dict_reverser(d):
    seen = set()
    return {v: k for k, v in d.items() if v not in seen or seen.add(v)}

这依赖于一个事实。在Python中add总是返回None。

假设字典中的值是唯一的:

Python 3:

dict((v, k) for k, v in my_map.items())

Python 2:

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