2010-10-19 7 views
38

C'è un modo più semplice per farlo in Python (2.7) ?: Nota: Questo non è niente di speciale, come mettere tutte le variabili locali in un dizionario. Solo quelli che ho specificato in una lista.Variabili Python come chiavi per dettare

apple = 1 
banana = 'f' 
carrot = 3 
fruitdict = {} 

# I want to set the key equal to variable name, and value equal to variable value 
# is there a more Pythonic way to get {'apple': 1, 'banana': 'f', 'carrot': 3}? 

for x in [apple, banana, carrot]: 
    fruitdict[x] = x # (Won't work) 
+1

Può variabili essere definite nel dict? Come fruitdict = dict (mela = 1, banana = 2, carota = 3)? –

+0

Non proprio, c'è un sacco di codice per ogni variabile, quindi sarebbe illeggibile. – ash

+0

Presumo che tu sappia che il codice non fa ciò che il commento dice che fa? Non è possibile tornare indietro dagli oggetti ai nomi a meno che non si trovi ciò che si desidera in un dizionario dello spazio dei nomi come locals() Si potrebbe tuttavia scrivere una funzione che ricerca queste variabili nel dizionario dello spazio dei nomi e assegna i valori trovati a quella chiave; vedi la risposta di jimbob. – Thomas

risposta

44
for i in ('apple', 'banana', 'carrot'): 
    fruitdict[i] = locals()[i] 
+6

'' dict ([(i, locals() [i]) per i in ('apple', 'banana', 'carrot')]) '' – dinya

11

La funzione globals() restituisce un dizionario contenente tutte le variabili globali.

>>> apple = 1 
>>> banana = 'f' 
>>> carrot = 3 
>>> globals() 
{'carrot': 3, 'apple': 1, '__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, 'banana': 'f'} 

C'è anche una funzione simile denominata locals().

Mi rendo conto che probabilmente non è esattamente ciò che si desidera, ma può fornire alcune informazioni su come Python fornisce l'accesso alle variabili.

Edit: Sembra che il problema può essere meglio risolto semplicemente utilizzando un dizionario, in primo luogo:

fruitdict = {} 
fruitdict['apple'] = 1 
fruitdict['banana'] = 'f' 
fruitdict['carrot'] = 3 
+0

Spiacente, devo averlo modificato dopo aver scritto la risposta. Ho solo bisogno delle variabili che ho specificato, non di tutti i locals() o globals() – ash

+0

@Jasie: ho aggiunto un esempio di semplicemente usando un dizionario in primo luogo, invece di scherzare con le variabili. –

1

Se si desidera associare le posizioni delle variabili stesse, c'è questo:

>>> apple = 1 
>>> banana = 'f' 
>>> carrot = 3 
>>> fruitdict = {} 
>>> fruitdict['apple'] = lambda : apple 
>>> fruitdict['banana'] = lambda : banana 
>>> fruitdict['carrot'] = lambda : carrot 
>>> for k in fruitdict.keys(): 
...  print k, fruitdict[k]() 
... 
carrot 3 
apple 1 
banana f 
>>> apple = 7 
>>> for k in fruitdict.keys(): 
...  print k, fruitdict[k]() 
... 
carrot 3 
apple 7 
banana f 
+0

Grazie, ma i numeri erano assegnazioni casuali (non era necessario un intervallo()). – ash

4

una battuta è: -

fruitdict = dict(zip(('apple','banana','carrot'), (1,'f', '3')) 
+0

Grazie, ma i numeri erano assegnazioni casuali (non era necessario un intervallo()). – ash

+0

Ora ci sono due liste – Dantalion

0

perché non si fa il contrario:

fruitdict = { 
     'apple':1, 
     'banana':'f', 
     'carrot':3, 
} 

locals().update(fruitdict) 

Aggiornamento:

non utilizzare il codice sopra controllare il commento.

dal modo in cui non si segnare il vars che si desidera ottenere non so forse in questo modo:

# All the vars that i want to get are followed by _fruit 
apple_fruit = 1 
carrot_fruit = 'f' 

for var in locals(): 
    if var.endswith('fruit'): 
     you_dict.update({var:locals()[var]) 
+4

Aggiornamento dei locals() 'come se fosse veramente malvagio. –

+0

Come dice un mio amico: 'buio voodoo' –

+0

d'accordo, ma la mia comprensione della sua domanda è che vuole ottenere solo le variabili __fruit e legume__; che è fondamentalmente impossibile a meno che non possa insegnare al suo programma a fare la differenza tra __fruit e legume__ e altre cose, o forse mi complicavo forse solo volere "carota, banana, mela" vars :) – mouad

0

Beh questo è un po ', umm ... non Pythonic ... brutto ... hacker ...

Ecco un frammento di codice supponendo che si desidera creare un dizionario di tutte le variabili locali si create dopo un checkpoint specifica è preso:

checkpoint = [ 'checkpoint' ] + locals().keys()[:] 
## Various local assigments here ... 
var_keys_since_checkpoint = set(locals().keys()) - set(checkpoint) 
new_vars = dict() 
for each in var_keys_since_checkpoint: 
    new_vars[each] = locals()[each] 

Nota che aggiungiamo esplicitamente la chiave "checkpoint" nella nostra cattura dello locals().keys() Anche io ne sto prendendo esplicitamente una parte, anche se in questo caso non dovrebbe essere necessario poiché il riferimento deve essere appiattito per aggiungerlo al ['checkpoint'] lista. Tuttavia, se si stesse utilizzando una variante di questo codice e si provasse a scorciatoiare i locals ['checkpoint'] + portion (because that key was already in() , for example) ... then, without the [:] slice you could end up with a reference to the locals(). Keys() `i cui valori cambierebbero man mano che si aggiungessero le variabili.

Off-line Non riesco a pensare a un modo per chiamare qualcosa come new_vars.update() con un elenco di chiavi da aggiungere/aggiornare. Quindi il ciclo for è molto portabile. Suppongo che una comprensione del dizionario possa essere usata nelle versioni più recenti di Python. Tuttavia, questo sembra non essere altro che un giro di golf del codice.

0

Questa domanda è stata praticamente una risposta, ma volevo solo dire che è stata divertente che hai detto

Questo non è niente di eccezionale, come mettere tutte le variabili locali in un dizionario .

Perché è in realtà "amatore"

quello che vuoi è:

apple = 1 
banana = 'f' 
carrot = 3 
fruitdict = {} 

# I want to set the key equal to variable name, and value equal to variable value 
# is there a more Pythonic way to get {'apple': 1, 'banana': 'f', 'carrot': 3}? 

names= 'apple banana carrot'.split() # I'm just being lazy for this post 
items = globals()     # or locals() 

for name in names: 
    fruitdict[name] = items[name] 

Onestamente, quello che stai facendo è solo la copia di elementi da un dizionario ad un altro.

(Greg Hewgill in pratica ha dato tutta risposta, ho appena fatto completare)

... e come le persone hanno suggerito, si dovrebbe probabilmente essere messa questi nel dizionario, in primo luogo, ma darò per scontato che per qualche motivo non è possibile

+0

quindi suppongo di non aver visto il post di jimbob ... praticamente la stessa cosa, semplicemente non chiamare i locali/globalmente più di una volta –

+0

Non credo che chiamare globalmente più di una volta sarebbe effettivamente più efficiente. –

+0

Es., se fai item = locals(); id (locals()) == id (items) otterresti uguaglianza. O se hai fatto items = locals(); b = 3; items ['b'] troverà la nuova variabile b, dal momento che in realtà non copiava le persone del luogo dettate agli elementi (che sarebbero più lenti). Se avessi fatto items = locals(). Copy() potrebbe esserci una piccola differenza; ma di nuovo la fase di copia è probabilmente più lenta dell'accesso al piccolo numero di elementi dalla gente del luogo. –

-1
a = "something" 
randround = {} 
randround['A'] = "%s" % a 

Ha funzionato.

+0

Dovrebbe essere '{'a': 'something'}' e stai ottenendo '{'A': 'something'}' ... stai codificando con forza la chiave 'A' – DarkCygnus

0

Sulla base della risposta da mouad, ecco un modo più divinatorio per selezionare le variabili in base a un prefisso:

# All the vars that I want to get start with fruit_ 
fruit_apple = 1 
fruit_carrot = 'f' 
rotten = 666 

prefix = 'fruit_' 
sourcedict = locals() 
fruitdict = { v[len(prefix):] : sourcedict[v] 
       for v in sourcedict 
       if v.startswith(prefix) } 
# fruitdict = {'carrot': 'f', 'apple': 1} 

si può anche mettere che in una funzione con prefisso e sourcedict come argomenti.

1

Qui è in una linea, senza dover digitare nuovamente una qualsiasi delle variabili o dei loro valori:

fruitdict.update({k:v for k,v in locals().copy().iteritems() if k[:2] != '__' and k != 'fruitdict'}) 
Problemi correlati