2013-07-19 10 views
9

Sto cercando un modo elegante per estrarre alcuni valori da un dict Python in valori locali.Un modo elegante per decomprimere valori di dict limitati in variabili locali in Python

qualcosa di equivalente a questo, ma più pulito per un elenco di valori più a lungo, e per la chiave/nomi di variabili più lunghi:

d = { 'foo': 1, 'bar': 2, 'extra': 3 } 
foo, bar = d['foo'], d['bar'] 

Mi è stato originariamente spera in qualcosa di simile al seguente:

foo, bar = d.get_tuple('foo', 'bar') 

Posso facilmente scrivere una funzione che non è male:

def get_selected_values(d, *args): 
    return [d[arg] for arg in args] 

foo, bar = get_selected_values(d, 'foo', 'bar') 

Ma continuo ad avere nascosto il sospetto che ci sia un altro modo integrato.

+2

Mi dispiace chiedere, ma * perché * vorresti farlo? –

+0

Potrebbe essere utile dare un'occhiata a una domanda su ambito e contesti su cui ho lavorato prima: . Questo potrebbe essere eccessivo per te, ma è stata una buona soluzione per me essere in grado di lavorare con oggetti dati scompattati da certe strutture dati e semplificare notevolmente la sintassi dell'applicazione di operazioni matematiche a loro. – ely

+0

Sto gestendo le strutture JSON in cui i valori 3-4 sono importanti per una logica di routing piuttosto complicata, ma in cui la struttura originale deve essere passata all'elaborazione finale. – DonGar

risposta

20

Si può fare qualcosa di simile

foo, bar = map(d.get, ('foo', 'bar')) 

o

foo, bar = itemgetter('foo', 'bar')(d) 

Questo potrebbe risparmiare un po 'di battitura, ma essenzialmente è lo stesso di quello che stai facendo (che è una buona cosa).

+6

Oppure usa 'foo, bar = itemgetter ('foo', 'bar') (d)' –

+0

@JonClements Questo è bello, penso che all'OP piacerà. –

+0

Ora mi sento in colpa perché non avevo notato che @DSM l'aveva messo come risposta alternativa ... –

1

Un po 'orribile, ma:

globals().update((k, v) for k, v in d.iteritems() if k in ['foo', 'bar']) 

nota, che mentre questo è possibile - è qualcosa che non si vuole veramente a fare come ti verrà inquinanti uno spazio dei nomi che dovrebbe solo essere lasciata all'interno del dict stesso ...

+5

Direi né elegante né una buona idea. – Marcin

+0

@Marcin Accetto ... aggiungerò una nota per renderlo un po 'più esplicito ... –

1

Bene, se conoscete i nomi prima del tempo, potete semplicemente fare come suggerite.

Se non li conosci prima del tempo, continua ad usare il dettato: ecco a cosa servono.

Se insisti, un'alternativa sarebbe:

varobj = object() 
for k,v in d.iteritems(): setattr(varobj,k,v) 

Dopo che le chiavi saranno variabili sulla varobj.

+1

Oh downvoter misterioso, scommetto che non puoi dire cosa non va in questo. – Marcin

+1

L'ambito della domanda non richiede né richiede commenti del tipo "se insisti."Penso che sia sicuro presumere che l'OP sia consapevole dei rischi (o che una discussione sui rischi possa andare nell'area dei commenti alla domanda, e non come una risposta). Attaccandoli come attributi su un oggetto non raggiungere l'obiettivo dichiarato di renderle variabili locali con alcuni nomi particolari.Se sei disposto a modificare il tono della risposta, in modo che non qualifichi nulla con le raccomandazioni in stile best practice, sarei felice di cambiare il voto una volta – ely

+1

@EMS Mi dispiace, ma non c'è nessuna regola che io debba dire a OP cosa vuole fare, senza valutare se sia o meno una buona idea. Francamente, il tuo atteggiamento è così offensivo che preferirei non Ho il tuo voto – Marcin

Problemi correlati