给定一本这样的字典:
my_map = {'a': 1, 'b': 2}
如何将此映射颠倒得到:
inv_map = {1: 'a', 2: 'b'}
给定一本这样的字典:
my_map = {'a': 1, 'b': 2}
如何将此映射颠倒得到:
inv_map = {1: 'a', 2: 'b'}
当前回答
除了上面建议的其他函数,如果你喜欢lambdas:
invert = lambda mydict: {v:k for k, v in mydict.items()}
或者,你也可以这样做:
invert = lambda mydict: dict( zip(mydict.values(), mydict.keys()) )
其他回答
如果值不是唯一的,并且你有点硬核:
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())
)
特别是对于大型字典,请注意,此解决方案的效率远远低于Python reverse / invert映射的答案,因为它在items()上循环多次。
我认为最好的方法是定义一个类。下面是一个“对称字典”的实现:
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中添加或删除值,并且您的反向字典将始终保持有效——如果您只是将整个字典反向一次,这是不正确的。
我知道这个问题已经有很多很好的答案,但我想分享这个非常简洁的解决方案,它也照顾到了重复值:
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。
有很多答案,但没有找到任何干净的东西,以防我们谈论的是一个具有非唯一值的字典。
解决办法是:
from collections import defaultdict
inv_map = defaultdict(list)
for k, v in my_map.items():
inv_map[v].append(k)
例子:
如果初始dict my_map ={“c”:1、“d”:5,' ':5 b: 10}
然后,运行上面的代码将得到:
{5: ['a', 'd'], 1: ['c'], 10: ['b']}
另一种更实用的方法是:
my_map = { 'a': 1, 'b':2 }
dict(map(reversed, my_map.items()))