给定一本这样的字典:
my_map = {'a': 1, 'b': 2}
如何将此映射颠倒得到:
inv_map = {1: 'a', 2: 'b'}
给定一本这样的字典:
my_map = {'a': 1, 'b': 2}
如何将此映射颠倒得到:
inv_map = {1: 'a', 2: 'b'}
当前回答
非双射地图的快速功能性解决方案(值不唯一):
from itertools import imap, groupby
def fst(s):
return s[0]
def snd(s):
return s[1]
def inverseDict(d):
"""
input d: a -> b
output : b -> set(a)
"""
return {
v : set(imap(fst, kv_iter))
for (v, kv_iter) in groupby(
sorted(d.iteritems(),
key=snd),
key=snd
)
}
理论上,这应该比命令式解决方案中那样逐个添加到集合(或添加到列表)更快。
不幸的是,值必须是可排序的,排序是由groupby要求的。
其他回答
我认为最好的方法是定义一个类。下面是一个“对称字典”的实现:
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中添加或删除值,并且您的反向字典将始终保持有效——如果您只是将整个字典反向一次,这是不正确的。
除了上面建议的其他函数,如果你喜欢lambdas:
invert = lambda mydict: {v:k for k, v in mydict.items()}
或者,你也可以这样做:
invert = lambda mydict: dict( zip(mydict.values(), mydict.keys()) )
如果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)]
我在循环'for'和方法'.get()'的帮助下写了这篇文章,我把字典的'map'名字改为'map1',因为'map'是一个函数。
def dict_invert(map1):
inv_map = {} # new dictionary
for key in map1.keys():
inv_map[map1.get(key)] = key
return inv_map
字典值为集合的一种情况。如:
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'}