2016-03-11 65 views
11

Vorrei scrivere una funzione che riceva un dizionario come argomento di input e restituisce un retro del dizionario di input in cui i valori del dizionario originale vengono utilizzati come chiavi per il dizionario restituito e le chiavi del dizionario originale vengono utilizzate come valore per il dizionario ritornato come spiegato di seguito:Come invertire un dizionario in Python?

dict = {'Accurate': ['exact', 'precise'], 
     'exact': ['precise'], 
     'astute': ['Smart', 'clever'], 
     'smart': ['clever', 'bright', 'talented']} 

a

dict = {'precise': ['accurate', 'exact'], 
     'clever': ['astute', 'smart'], 
     'talented': ['smart'], 
     'bright': ['smart'], 
     'exact': ['accurate'], 
     'smart': ['astute']} 

l'elenco dei valori nel dizionario restituiti dovrebbero essere ordinati in ordine crescente. La maiuscola non ha importanza. Ciò significa che tutte le parole devono essere convertite in lettere minuscole. Ad esempio la parola "Accurate" è in maiuscolo nel dizionario originale ma nel dizionario restituito è scritta con tutte le lettere minuscole.

#My code is: 
from collections import defaultdict 
def reverse_dictionary(input_dict): 
    d = defaultdict(list) 
    for v,k in input_dict.items(): 
     d[k].append(v) 
     return d 

ma restituisce questo errore se:

Error in evaluating function: 
TypeError at line 6 
unhashable type: 'list' 
+3

Il problema è che non è possibile utilizzare alcun oggetto come chiave: questi oggetti devono essere immutabili, quindi il loro hash va lue non cambia dopo essere stati aggiunti al dizionario. Nel tuo caso, gli elenchi sono mutabili, quindi non possono essere usati come chiavi. Potresti invece convertirli in tuple. –

+2

Benvenuti in StackExchange! Potrebbe essere utile dare più pensiero a questo problema. Ad esempio, perché "Accurato": ["esatto", "preciso"] "diventa" preciso ": [" preciso "," esatto "]" invece di "esatto": ["preciso", "preciso" '] '? Per quanto riguarda il tuo messaggio di errore, una lista non può essere la tua chiave dict, ma penso che il problema più grande sia che il tuo compito deve essere chiarito. –

+0

Inoltre, i dizionari non possono essere ordinati. –

risposta

5

Si può fare molto semplicemente l ike this:

newdict = {} 
for key, value in olddict.items(): 
    for string in value: 
     newdict.setdefault(string, []).append(key) 
+0

Sempre, sempre, usa sempre le spiegazioni del dittito quando si presenta la possibilità :) – DaveBensonPhillips

+0

Puoi fare un esempio? Non riuscivo a pensare a uno che avrebbe funzionato. – zondo

+0

Oh, oops - Pensavo fosse quello che avevi fatto, ero stupido.Non stavo cercando di essere condiscendente, ma mi rendo conto che è esattamente come sono venuto fuori, scuse – DaveBensonPhillips

4

vorrei iniziare scambiando le chiavi/valori utilizzando un dict di default:

output_dict = defaultdict(list) 
for key, values in input_dict.items(): 
    for value in values: 
     output_dict[value.lower()].append(key.lower()) 

E infine l'ordinamento:

for key, values in output_dict.items(): 
    output_dict[key] = sorted(values) 
4

Utilizzare una comprensione del ditt!

>>> evil_petting_zoo = {'bear':3, 'crocodile':1,'kangaroo':2,'goat':0} 
>>> evil_petting_zoo.items() 

dict_items([('bear', 3), ('crocodile', 1), ('kangaroo', 2), ('goat', 0)]) 

>>> {i[1]:i[0] for i in evil_petting_zoo.items()} 

{3: 'bear', 1: 'crocodile', 2: 'kangaroo', 0: 'goat'} 

TL; DR:

{i[1]:i[0] for i in myDictionary.items()} 
1

Come invertire un dict:

def reverse(org): 
    return {v: k for k, v in org.items()} 

print(reverse({1: 'a', 2: 'b'})) 
# {'a': 1, 'b': 2} 
+0

questa risposta è più adatta al mio problema (e per una chiave standard: valore dettato). Grazie ;) –

0

questa è la risposta, senza l'utilizzo di alcun modulo:

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