Answers:
对于Python 2.7.x
inv_map = {v: k for k, v in my_map.iteritems()}
对于Python 3+:
inv_map = {v: k for k, v in my_map.items()}
The order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon
。无法保证会保持这样的状态,因此不要依赖于Dict
具有与相同行为的代码OrderedDict
。
假设字典中的值是唯一的:
dict((v, k) for k, v in my_map.iteritems())
iteritems()
将要输出的顺序,因此可以假定将为某个非唯一值分配一个任意键,这种方式在某些情况下显然可以重现,但通常不会。
iteritems()
方法,这种方法将行不通。items()
如接受的答案所示,在此处使用。同样,字典理解比调用还要漂亮dict
。
如果中的值my_map
不是唯一的:
inv_map = {}
for k, v in my_map.iteritems():
inv_map[v] = inv_map.get(v, [])
inv_map[v].append(k)
inv_map.get(v, [])
如果有一个列表,则返回已经添加的列表,因此分配不会重置为空列表。setdefault
仍然会更漂亮。
inv_map.setdefault(v, set()).add(k)
。
my_map.items()
代替my_map.iteritems()
。
为此,同时保留映射类型(假设它是a dict
或dict
子类):
def inverse_mapping(f):
return f.__class__(map(reversed, f.items()))
尝试这个:
inv_map = dict(zip(my_map.values(), my_map.keys()))
(请注意,字典视图上的Python文档明确地保证了这一点,.keys()
并且.values()
其元素具有相同的顺序,这使得上述方法可以工作。)
或者:
inv_map = dict((my_map[k], k) for k in my_map)
或使用python 3.0的dict理解
inv_map = {my_map[k] : k for k in my_map}
另一种更实用的方法:
my_map = { 'a': 1, 'b':2 }
dict(map(reversed, my_map.items()))
filter
并且map
应该死掉并纳入列表理解中,而不是增加变体”。
dict
与其他测绘类型,如collections.OrderedDict
或collections.defaultdict
这扩展了Robert的答案,适用于字典中的值不是唯一的情况。
class ReversibleDict(dict):
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.iteritems():
revdict.setdefault(v, []).append(k)
return revdict
实现受到限制,因为您不能使用reversed
两次并取回原始文件。因此它不是对称的。已通过Python 2.6测试。这是一个我用来打印结果字典的用例。
如果您宁愿使用a而set
不是a list
,并且可能存在对此有意义的无序应用程序,而不是setdefault(v, []).append(k)
use setdefault(v, set()).add(k)
。
revdict.setdefault(v, set()).add(k)
set
。这是适用于此的固有类型。如果我要查找所有值都不为1
或的键2
怎么办?然后我可以做d.keys() - inv_d[1] - inv_d[2]
(在Python 3中)
我们还可以使用重复键反转字典defaultdict
:
from collections import Counter, defaultdict
def invert_dict(d):
d_inv = defaultdict(list)
for k, v in d.items():
d_inv[v].append(k)
return d_inv
text = 'aaa bbb ccc ddd aaa bbb ccc aaa'
c = Counter(text.split()) # Counter({'aaa': 3, 'bbb': 2, 'ccc': 2, 'ddd': 1})
dict(invert_dict(c)) # {1: ['ddd'], 2: ['bbb', 'ccc'], 3: ['aaa']}
看这里:
与使用的等效技术相比,此技术更简单,更快
dict.setdefault()
。
例如,您有以下字典:
dict = {'a': 'fire', 'b': 'ice', 'c': 'fire', 'd': 'water'}
而且您想以相反的形式获取它:
inverted_dict = {'fire': ['a', 'c'], 'ice': ['b'], 'water': ['d']}
第一个解决方案。要在字典中反转键值对,请使用for
-loop方法:
# Use this code to invert dictionaries that have non-unique values
inverted_dict = dict()
for key, value in 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 dict.items()}
第三解。使用还原反转方法(取决于第二种解决方案):
# Use this code to invert dictionaries that have lists of values
dict = {value: key for key in inverted_dict for value in my_map[key]}
dict
保留,不应该用于变量名
my_map
是
dictio()
?你是说dict()
吗
列表和字典理解的结合。可以处理重复的钥匙
{v:[i for i in d.keys() if d[i] == v ] for k,v in d.items()}
如果值不是唯一的,并且您有点硬核:
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()
多次。
-1
因为它仍然可以回答问题,仅是我的意见。
除了上面建议的其他功能之外,如果您喜欢lambdas:
invert = lambda mydict: {v:k for k, v in mydict.items()}
或者,您也可以采用这种方式:
invert = lambda mydict: dict( zip(mydict.values(), mydict.keys()) )
我认为最好的方法是定义一个类。这是“对称字典”的实现:
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的这种可能性。
这处理非唯一值,并保留了唯一情况的大部分外观。
inv_map = {v:[k for k in my_map if my_map[k] == v] for v in my_map.itervalues()}
对于Python 3.x,请替换itervalues
为values
。
函数对于类型列表的值是对称的;执行reverse_dict(reverse_dict(dictionary))时,元组被覆盖到列表中
def reverse_dict(dictionary):
reverse_dict = {}
for key, value in dictionary.iteritems():
if not isinstance(value, (list, tuple)):
value = [value]
for val in value:
reverse_dict[val] = reverse_dict.get(val, [])
reverse_dict[val].append(key)
for key, value in reverse_dict.iteritems():
if len(value) == 1:
reverse_dict[key] = value[0]
return reverse_dict
由于字典在字典中需要一个与值不同的唯一键,因此我们必须将反转的值附加到要包含在新的特定键中的排序列表中。
def r_maping(dictionary):
List_z=[]
Map= {}
for z, x in dictionary.iteritems(): #iterate through the keys and values
Map.setdefault(x,List_z).append(z) #Setdefault is the same as dict[key]=default."The method returns the key value available in the dictionary and if given key is not available then it will return provided default value. Afterward, we will append into the default list our new values for the specific key.
return Map
非双射映射的快速功能解决方案(值不是唯一的):
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要求排序。
n
原始字典中的元素,O(n log n)
由于需要对字典项进行排序,因此您的方法具有时间复杂性,而幼稚的命令式方法具有O(n)
时间复杂性。就我所知,您的方法dict
在实践中可能要快到令人惊讶的大,但从理论上讲它肯定不会更快。
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']}
dict.items
(或iteritems
在Python 2中)同时迭代键/值对比在迭代键时分别提取每个值更有效。此外,您没有为重复的答案添加任何解释。
def reverse_dictionary(input_dict):
out = {}
for v in input_dict.values():
for value in v:
if value not in out:
out[value.lower()] = []
for i in input_dict:
for j in out:
if j in map (lambda x : x.lower(),input_dict[i]):
out[j].append(i.lower())
out[j].sort()
return out
这段代码是这样的:
r = reverse_dictionary({'Accurate': ['exact', 'precise'], 'exact': ['precise'], 'astute': ['Smart', 'clever'], 'smart': ['clever', 'bright', 'talented']})
print(r)
{'precise': ['accurate', 'exact'], 'clever': ['astute', 'smart'], 'talented': ['smart'], 'bright': ['smart'], 'exact': ['accurate'], 'smart': ['astute']}
没有什么完全不同,只是Cookbook重写了一些食谱。还通过保留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.X替换mapping.items()
与mapping.iteritems()
在我的机器上,运行速度比这里的其他示例更快
dict
,然后最后转换为所需的类(而不是从正确类型的类开始),在我看来,这会导致完全可以避免的性能下降。
我在循环“ 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
如果值不是唯一的,并且可能是哈希(一维):
for k, v in myDict.items():
if len(v) > 1:
for item in v:
invDict[item] = invDict.get(item, [])
invDict[item].append(k)
else:
invDict[v] = invDict.get(v, [])
invDict[v].append(k)
如果需要更深层次地进行递归,则只需一个维度即可:
def digList(lst):
temp = []
for item in lst:
if type(item) is list:
temp.append(digList(item))
else:
temp.append(item)
return set(temp)
for k, v in myDict.items():
if type(v) is list:
items = digList(v)
for item in items:
invDict[item] = invDict.get(item, [])
invDict[item].append(k)
else:
invDict[v] = invDict.get(v, [])
invDict[v].append(k)
{"foo": "bar"}
为{'b': ['foo'], 'a': ['foo'], 'r': ['foo']}
并引发异常myDict
。我不确定您要在此处实现哪种行为,但实际上实现的是几乎没人想要的东西。
my_map.items()
的作品,以及