2012-12-05 12 views
7

Sono un principiante in Python, ma ho provato questa sintassi e non riesco a capirlo - il che è stato davvero sconcertante.Confronto tra due valori chiave di dizionari e restituzione del valore se corrisponde

crucial = {'eggs': '','ham': '','cheese': ''} 
dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500} 

if crucial.keys() in dishes.keys(): 
    print dishes[value] 

Quello che voglio fare è - se fondamentale ha una chiave (in questo caso, eggs) nei piatti, verrà restituito 2. Sembra abbastanza semplice, ma credo che dovrei fare qualche tipo di sintassi da qualche parte. Se qualcuno potesse guidarmi un po ', sarebbe molto apprezzato.

Il vero dizionario con cui sto confrontando è lungo circa 150 tasti, ma spero che questo codice sia abbastanza semplice.

+0

Quale versione di Python stai usando? – Blckknght

risposta

10

È necessario scorrere i tasti in modo cruciale e confrontare ciascuno con i tasti piatti. Quindi una versione direttamente modificata del tuo codice.

for key in crucial.keys(): 
    if key in dishes.keys(): 
     print dishes[key] 

Potrebbe essere meglio indicato come (non c'è bisogno di specificare .keys):

for key in crucial: 
    if key in dishes: 
     print dishes[key] 
+0

keys() non è necessario in questo caso, per impostazione predefinita, l'iterazione in un dizionario è sufficiente. "per key in critical.keys()" equivale a "per key in cruciale" –

+0

Sei corretto, e una lista di comprensione è l'opzione migliore, tuttavia ho pensato che un esempio esplicito sarebbe stato utile per un principiante Python. – timc

+0

Grazie! Questo è stato incredibilmente utile! Sto leggendo la comprensione della lista ora per imparare un po 'di più ... – yrekkehs

1

usando di lista è buono

[ dishes[x] for x in crucial if dishes.has_key(x) ] 

o, come da gnibbler:

[ dishes[x] for x in crucial if x in dishes ] 

questa espressione verrà iterata cruciale ogni chiave in modo cruciale, se chiave in piatti, restituirà il valore della stessa chiave in piatti, infine, restituisce un elenco di tutti i valori di corrispondenza.

oppure, è possibile utilizzare in questo modo, (set (fondamentale) & set (piatti)) restituire le chiavi comuni di entrambi i set, quindi iterare questo set e restituire i valori nelle stoviglie.

[ dishes[x] for x in set (crucial) & set(dishes) ] 
+1

'has_key' è deprecato. Si prega di usare 'x in piatti' invece –

+1

O anche' [piatti [x] per x in set (cruciale) .intersection (piatti)] 'per radere un enorme 70ns :) – RocketDonkey

+0

che bello! .. –

0

Se non si ha già familiarità con REPL di Python (Read-Valutare-Stampa-Loop - quella cosa in cui si digita il codice, premere Invio e valuta immediatamente) , sarebbe un buon strumento qui.

Così iniziamo ad analizzare il codice.

crucial = {'eggs': '','ham': '','cheese': ''} 
dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500} 

Abbastanza semplice. Anche se noto che non hai alcun valore nel dizionario crucials. Non sono sicuro che questa sia un'abbreviazione per il tuo esempio o se ti interessi semplicemente le chiavi. Se ti preoccupi solo delle chiavi, suppongo che tu stia usando un dizionario per garantire l'unicità. In tal caso, dovresti controllare lo set data structure.

Esempio:

crutial = set(['cheese', 'eggs', 'ham']) 

Proseguendo abbiamo

if crucial.keys() in dishes.keys(): 

qui si utilizza il in comparison operator. Esempio:

5 in [5, 4] #True 
3 in [5, 4] #False 

Se valutiamo crucial.keys() e dishes.keys() otteniamo

>>> crucial.keys() 
['cheese', 'eggs', 'ham'] 
>>> dishes.keys() 
['eggs', 'bacon', 'sausage', 'spam'] 

così durante l'esecuzione il codice valuta come

['cheese', 'eggs', 'ham'] in ['eggs', 'bacon', 'sausage', 'spam'] 

che restituisce False perché il valore ['eggs', 'bacon', 'sausage'] (che è una lista) non è nella lista ['eggs', 'bacon', 'sausage', 'spam'] (in effetti non ci sono liste all'interno di quella lista, solo stringhe).

Così si sta valutando come

if False: 
    print dishes[value] #note value is not defined. 

E invece sembra aver mescolato/confondere l'operatore in che restituisce un valore booleano e la per iteratore (for item in collection). C'è una sintassi per questo genere di cose. Si chiama list comprehensions che puoi trovare esempi di risposte in @ShawnZhang e @ kmad. Puoi pensare ad esso come un modo teso per filtrare e modificare (mappare) una collezione, restituendo di conseguenza un elenco. Non voglio entrare troppo in profondità o finirò con un'introduzione alla programmazione funzionale.

L'altra opzione è utilizzare l'iterazione for .. in e gli operatori in separatamente. Questa è la soluzione che ha dato @timc. Tali soluzioni sono probabilmente più familiari o più facili per i principianti. Separa chiaramente il comportamento di iterazione e filtraggio. È anche più simile a quello che verrebbe scritto in altri linguaggi di programmazione che non hanno un equivalente di list comprehensions. Chi lavora molto in Python probabilmente preferirebbe la sintassi di comprensione.

+0

vossad01, apprezzo la risposta. La tua spiegazione l'ho salvata ... ed è un po 'più evidente sul motivo per cui non stava funzionando con i miei sforzi per tentativi ed errori! – yrekkehs

2

Se si utilizza Python 3, il metodo keys dei dizionari segue l'interfaccia set. Ciò significa che puoi fare un'intersezione delle chiavi dei due dizionari usando l'operatore &.

for key in crucial.keys() & dishes.keys(): 
    print(dishes[key]) 

Oppure, se avete bisogno di un elenco dei valori:

result = [dishes[key] for key in crucial.keys() & dishes.keys()] 

In Python 2 si potrebbe gestire la stessa cosa con la creazione esplicitamente set (forse dal generatore iterkeys), ma probabilmente sarebbe meglio fare semplicemente un giro sui tasti, come suggeriscono molte delle altre risposte.

Ecco una variazione del ciclo che non penso di aver visto nessun altro fare. Il ciclo esterno ottiene sia le chiavi che i valori dal codice dishes, quindi non è necessario cercare separatamente il valore per chiave.

for key, value in dishes.iteritems(): # use items() in Python 3 
    if key in crucial: 
     print value 
+0

Strano come questa risposta sia trascurata. Provato. Funziona alla grande e ha cambiato il mio modo di scrivere certi tipi di codice. –

-1
crucial = {'eggs': '','ham': '','cheese': ''} 
dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500} 
for key in set(dishes.keys()) & set(crucial.keys()): 
    print dishes[key] 

Allo stesso modo, è possibile avere set(dishes.keys()) - set(crucial.keys()), set(dishes.keys()) | set(crucial.keys()) o set(dishes.keys())^set(crucial.keys()).

+0

in questo modo, è possibile impostare (dishes.keys()) - set (crucial.keys()), set (dishes.keys()) | set (crucial.keys()), o set (dishes.keys())^set (crucial.keys()) – JoeLiu

+1

Le risposte al solo codice generalmente non sono molto buone. Devi aggiungere una spiegazione ** nella risposta **. –

Problemi correlati