2009-03-27 28 views
12

Quindi, le funzioni Python possono restituire più valori. Mi ha colpito che sarebbe stato conveniente (anche se un po 'meno leggibile) se fosse possibile seguire quanto segue.Passaggio di funzioni che hanno più valori di ritorno come argomenti in Python

a = [[1,2],[3,4]] 

def cord(): 
    return 1, 1 

def printa(y,x): 
    print a[y][x] 

printa(cord()) 

... ma non lo è. Sono consapevole che puoi fare la stessa cosa riversando entrambi i valori di ritorno in variabili temporanee, ma non sembra elegante. Potrei anche riscrivere l'ultima riga come "printa (cord() [0], cord() [1])", ma ciò dovrebbe eseguire cord() due volte.

Esiste un modo elegante ed efficiente per farlo? O dovrei semplicemente vedere quella citazione sull'ottimizzazione prematura e dimenticarla?

risposta

20
printa(*cord()) 

Il * ecco un operatore espansione argomento ... beh dimenticato come si chiama tecnicamente, ma in questo contesto si prende una lista o tupla e si espande fuori così la funzione sfrutta ogni elemento di lista/tupla come un argomento separato.

E 'fondamentalmente l'inverso del * si potrebbe usare per catturare tutti gli argomenti non di parole chiave in una definizione di funzione:

def fn(*args): 
    # args is now a tuple of the non-keyworded arguments 
    print args 

fn(1, 2, 3, 4, 5) 

stampe (1, 2, 3, 4, 5)

fn(*[1, 2, 3, 4, 5]) 

fa lo stesso.

+1

È una tupla. :-) –

+0

E la documentazione: http://docs.python.org/tutorial/controlflow.html#tut-unpacking-arguments – regan

+0

Grazie Jason, l'ho modificato. –

6

Prova questo:

>>> def cord(): 
...  return (1, 1) 
... 
>>> def printa(y, x): 
...  print a[y][x] 
... 
>>> a=[[1,2],[3,4]] 
>>> printa(*cord()) 
4 

La star dice sostanzialmente "utilizzare gli elementi di questa collezione come argomenti posizionali." Si può fare lo stesso con un dict per argomenti chiave che utilizzano due stelle:

>>> a = {'a' : 2, 'b' : 3} 
>>> def foo(a, b): 
... print a, b 
... 
>>> foo(**a) 
2 3 
4

In realtà, Python in realtà non tornare più valori, restituisce un valore che può essere più valori confezionati in una tupla. Il che significa che è necessario "decomprimere" il valore restituito per avere multipli. una dichiarazione come

x,y = cord() 

lo fa, ma direttamente tramite il valore di ritorno come avete fatto in

printa(cord()) 

non significa, è per questo che è necessario utilizzare l'asterisco. Forse un bel termine potrebbe essere "tuple decompressione implicita" o "tuple disimballare senza incarico".

Problemi correlati