给定一本这样的字典:

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

如何将此映射颠倒得到:

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

当前回答

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

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的lambda解决方案。x版本:

d1 = dict(alice='apples', bob='bananas')
d2 = dict(map(lambda key: (d1[key], key), d1.keys()))
print(d2)

结果:

{'apples': 'alice', 'bananas': 'bob'}

此解决方案不检查重复项。

一些评论:

构造可以从外部作用域访问d1,所以我们只能 传入当前键。它返回一个元组。 dict()构造函数接受一个元组列表。它 也接受映射的结果,所以我们可以跳过转换到 列表。 这个解决方案没有显式的for循环。它还避免了对那些数学不好的人使用列表理解;-)

我会在python2中这样做。

inv_map = {my_map[x] : x for x in my_map}

这扩展了Robert的回答,适用于字典中的值不是唯一的情况。

class ReversibleDict(dict):
    # Ref: https://stackoverflow.com/a/13057382/
    def reversed(self):
        """
        Return a reversed dict, with common values in the original dict
        grouped into a list in the returned dict.

        Example:
        >>> d = ReversibleDict({'a': 3, 'c': 2, 'b': 2, 'e': 3, 'd': 1, 'f': 2})
        >>> d.reversed()
        {1: ['d'], 2: ['c', 'b', 'f'], 3: ['a', 'e']}
        """
        
        revdict = {}
        for k, v in self.items():
            revdict.setdefault(v, []).append(k)
        return revdict

该实现的局限性在于您不能使用反转两次并获得原始数据。它本身不是对称的。它是用Python 2.6测试的。这是一个用例,我是如何使用打印结果字典。

如果你更喜欢使用集合而不是列表,并且可能存在无序的应用程序,这是有意义的,而不是setdefault(v, []).append(k),使用setdefault(v, set()).add(k)。

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

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。

即使在原始字典中有非唯一的值,这种方法也有效。

def dict_invert(d):
    '''
    d: dict
    Returns an inverted dictionary 
    '''
    # Your code here
    inv_d = {}
    for k, v in d.items():
        if v not in inv_d.keys():
            inv_d[v] = [k]
        else:
            inv_d[v].append(k)
        inv_d[v].sort()
        print(f"{inv_d[v]} are the values")
        
    return inv_d