2011-09-05 18 views
8

Na przykład, nazwać tę funkcję przez przepuszczanie słownika jako parametru:klucze inwertowany i wartości oryginalnej słowniku

>>> 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']} 

Jeśli

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

Mogę jedynie odwrócić tę mapę, aby uzyskać:

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

za pomocą tego

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

Ktoś wie, jak to zrobić w moim przypadku?

Odpowiedz

13

Można użyć defaultdict z listy:

>>> 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']} 

Jeśli nie obchodzi czy masz dict lub defaultdict można pominąć ostatni krok und użyć defaultdict bezpośrednio.

+1

Zauważ, że ostatnia linia konwersji 'collections.defaultdict' powrotem do normalnej' dict'- bardzo często nie jest konieczne, a nawet niepożądane. –

+0

@MikeGraham Czy możesz wyjaśnić, dlaczego? Często robię więcej błędów, gdy nie dodaję tego wiersza (ponieważ jeśli szukasz i nie istniejący klucz, doda go). – tomasyany

8

Możesz prawdopodobnie użyć tutaj defaultdict lub setdefault tutaj.

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

EDIT W Pythonie 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}) 

wyjściowa:

{1: ['a'], 2: ['b', 'd'], 3: ['c']} 
{3: ['a', 'c', 'b']} 
{1: ['b', 'd'], 2: ['a', 'c']} 
Powiązane problemy