2011-09-05 34 views
8

例如,我通過傳遞一個字典作爲參數調用這個函數的值:反轉鍵和原來的字典

>>> inv_map({'a':1, 'b':2, 'c':3, 'd':2}) 
{1: ['a'], 2: ['b', 'd'], 3: ['c']} 
>>> inv_map({'a':3, 'b':3, 'c':3}) 
{3: ['a', 'c', 'b']} 
>>> inv_map({'a':2, 'b':1, 'c':2, 'd':1}) 
{1: ['b', 'd'], 2: ['a', 'c']} 

如果

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

我只能反轉這個圖可以得到:

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

使用此

dict((v,k) for k, v in map.iteritems()) 

任何人都知道如何爲我的情況做到這一點?

回答

13

可以使用defaultdict與列表:

>>> from collections import defaultdict 
>>> m = {'a': 2, 'b': 1, 'c': 2, 'd': 1} 
>>> dd = defaultdict(list) 
>>> for k, v in m.iteritems(): 
...  dd[v].append(k) 
... 
>>> dict(dd) 
{1: ['b', 'd'], 2: ['a', 'c']} 

如果你,如果你有一個字典或defaultdict不在乎,你可以省略最後一步UND直接使用defaultdict。

+1

注意,最後一行轉換的'collections.defaultdict'回到正常'dict'-通常是不必要的,甚至是不希望的。 –

+0

@MikeGraham你能解釋一下爲什麼要這樣嗎?當不添加該行時,我經常會犯更多錯誤(因爲如果您查找並且不存在密鑰,它會添加它)。 – tomasyany

8

您可以在這裏使用defaultdictsetdefault

def invertDictionary(orig_dict): 
    result = {} # or change to defaultdict(list) 
    for k, v in orig_dict.iteritems(): 
     result.setdefault(v, []).append(k) 
2

EDIT在蟒2.7:

from itertools import groupby 
def inv_map(d): 
    return {k : [i[0] for i in list(v)] for k, v in groupby(d.items(),lambda x:x[1])} 

print inv_map({'a':1, 'b':2, 'c':3, 'd':2}) 
print inv_map({'a':3, 'b':3, 'c':3}) 
print inv_map({'a':2, 'b':1, 'c':2, 'd':1}) 

輸出:

{1: ['a'], 2: ['b', 'd'], 3: ['c']} 
{3: ['a', 'c', 'b']} 
{1: ['b', 'd'], 2: ['a', 'c']}