给定一本这样的字典:

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

如何将此映射颠倒得到:

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

当前回答

我认为最好的方法是定义一个类。下面是一个“对称字典”的实现:

class SymDict:
    def __init__(self):
        self.aToB = {}
        self.bToA = {}

    def assocAB(self, a, b):
        # Stores and returns a tuple (a,b) of overwritten bindings
        currB = None
        if a in self.aToB: currB = self.bToA[a]
        currA = None
        if b in self.bToA: currA = self.aToB[b]

        self.aToB[a] = b
        self.bToA[b] = a
        return (currA, currB)

    def lookupA(self, a):
        if a in self.aToB:
            return self.aToB[a]
        return None

    def lookupB(self, b):
        if b in self.bToA:
            return self.bToA[b]
        return None

如果需要,删除和迭代方法很容易实现。

这种实现比颠倒整个字典(这似乎是本页上最流行的解决方案)更有效。更不用说,您可以随心所欲地从SymDict中添加或删除值,并且您的反向字典将始终保持有效——如果您只是将整个字典反向一次,这是不正确的。

其他回答

不是完全不同的东西,只是从食谱中重写了一点。它通过保留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()

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

例如,你有以下字典:

my_dict = {'a': 'fire', 'b': 'ice', 'c': 'fire', 'd': 'water'}

你想要得到这样一个倒立的形式

inverted_dict = {'fire': ['a', 'c'], 'ice': ['b'], 'water': ['d']}

第一个解决方案。要在字典中反转键值对,请使用For循环方法:

# Use this code to invert dictionaries that have non-unique values

inverted_dict = dict()
for key, value in my_dict.items():
    inverted_dict.setdefault(value, list()).append(key)

第二个解决方案。使用字典理解方法进行反转:

# Use this code to invert dictionaries that have unique values

inverted_dict = {value: key for key, value in my_dict.items()}

第三个解决方案。使用反转方法(依赖于第二个解决方案):

# Use this code to invert dictionaries that have lists of values

my_dict = {value: key for key in inverted_dict for value in my_map[key]}

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

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 +:

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

Python 2:

inv_map = {v: k for k, v in my_map.iteritems()}
def invertDictionary(d):
    myDict = {}
  for i in d:
     value = d.get(i)
     myDict.setdefault(value,[]).append(i)   
 return myDict
 print invertDictionary({'a':1, 'b':2, 'c':3 , 'd' : 1})

这将提供输出为:{1:(' a ', ' d '), 2: [b], 3: [' c ']}