2009-03-27 24 views
12

Funkcje Pythona mogą zwracać wiele wartości. Uderzyło mnie, że byłoby to wygodne (choć nieco mniej czytelne), gdyby następujące rzeczy były możliwe.Przekazywanie funkcji, które mają wiele wartości zwracanych jako argumenty w języku Python

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

def cord(): 
    return 1, 1 

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

printa(cord()) 

... ale tak nie jest. Jestem świadomy, że możesz zrobić to samo, przesyłając obie wartości zwracane do zmiennych tymczasowych, ale nie wygląda to tak elegancko. Mógłbym również przepisać ostatnią linię jako "printa (cord() [0], cord() [1])", ale to wykonałoby dwa razy przewód().

Czy istnieje elegancki i skuteczny sposób na zrobienie tego? A może powinienem zobaczyć ten cytat o przedwczesnej optymalizacji i zapomnieć o tym?

Odpowiedz

20
printa(*cord()) 

* tutaj jest operatorem ekspansja argumentem ... dobrze nie pamiętam, co to technicznie nazywa, ale w tym kontekście przyjmuje listy lub krotki i rozszerza ją więc funkcja widzi każdy element listy/krotki jako osobny argument.

Jest to w zasadzie odwrotnością * można wykorzystać, aby uchwycić wszystkie argumenty niż słowa kluczowe w definicji funkcji:

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

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

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

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

robi to samo.

+1

To krotka. :-) –

+0

A dokumentacja: http://docs.python.org/tutorial/controlflow.html#tut-unpacking-arguments – regan

+0

Dzięki Jason, redagowałem to w. –

6

Spróbuj tego:

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

Gwiazda zasadzie mówi „wykorzystywać elementy tej kolekcji jak pozycyjnych argumentów.” Można zrobić to samo z dict argumentów kluczowych wykorzystujących dwie gwiazdy:

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

Właściwie Python naprawdę nie zwracać wiele wartości, zwraca jedną wartość, która może mieć wiele wartości pakowane w krotce. Co oznacza, że ​​musisz "rozpakować" zwróconą wartość, aby mieć wielokrotności. Oświadczenie jak

x,y = cord() 

robi, ale bezpośrednio przy użyciu wartości zwracanej jak ty w

printa(cord()) 

nie, to dlaczego trzeba użyć gwiazdki. Być może dobrym określeniem może być "ukryte rozpakowywanie krotek" lub "rozpakowywanie krotek bez przydziału".