假设有如下字典:
my_map = {'a': 1, 'b': 2}
如何反转该地图以获得以下结果:
inv_map = {1: 'a', 2: 'b'}
假设有如下字典:
my_map = {'a': 1, 'b': 2}
inv_map = {1: 'a', 2: 'b'}
词典中值为集合的情况,例如:
some_dict = {"1":{"a","b","c"},
"2":{"d","e","f"},
"3":{"g","h","i"}}
逆变表示为:some_dict = {vi: k for k, v in some_dict.items() for vi in v}
输出结果如下:{'c': '1',
'b': '1',
'a': '1',
'f': '2',
'd': '2',
'e': '2',
'g': '3',
'h': '3',
'i': '3'}
列表和字典推导式的结合。可以处理重复的键。
{v:[i for i in d.keys() if d[i] == v ] for k,v in d.items()}
我发现这个版本比一个有10000个键的字典的已接受版本要快10%以上。
d = {i: str(i) for i in range(10000)}
new_d = dict(zip(d.values(), d.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)}
set.add
永远返回 None
的事实。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反转/反向映射 要低效得多,因为它多次循环 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中的值,您的反向字典始终有效--如果您仅仅反转整个字典一次,则不是这种情况。
dictresize
,但这种方法却剥夺了 Python 这种可能性。 - Mark Ameryinv_map = {v:[k for k in my_map if my_map[k] == v] for v in my_map.itervalues()}
itervalues
替换为values
。dict([(value, key) for key, value in d.items()])
my_map = {'a': 1, 'b': 2}
inv_map= {}
for key in my_map.keys() :
val = my_map[key]
inv_map[val] = key