Zrozumienie lambdy w Pythonie i używanie jej do przekazywania wielu argumentów

90

Po przeczytaniu wszystkiego, co mogę znaleźć na lambdzie, nadal nie rozumiem, jak zrobić to, co chcę.

Każdy korzysta z przykładu:

lambda x, y : x + y

Dlaczego musisz podać oba xi yprzed :? Jak sprawić, by zwracał wiele argumentów?

na przykład:

self.buttonAdd_1 = Button(self, text='+', command=lambda : self.calculate(self.buttonOut_1.grid_info(), 1))

To działa dobrze. Ale poniższy kod nie:

self.entry_1.bind("<Return>", lambda : self.calculate(self.buttonOut_1.grid_info(), 1))

Daje błąd:

TypeError: () nie przyjmuje argumentów (podano 1)

Talisin
źródło

Odpowiedzi:

136

Dlaczego musisz podać „x” i „y” przed „:”?

Ponieważ lambda jest (koncepcyjnie) taka sama jak funkcja, po prostu zapisana w wierszu. Twój przykład jest równoważny z

def f(x, y) : return x + y

tylko bez wiązania go z nazwą taką jak f.

Jak sprawić, by zwracał wiele argumentów?

Tak samo jak w przypadku funkcji. Najlepiej jest zwrócić krotkę:

lambda x, y: (x+y, x-y)

Albo lista, klasa, czy cokolwiek.

Na sprawę self.entry_1.bindpowinien odpowiedzieć Demosthenex.

phipsgabler
źródło
2
Aby naprawdę wydobyć z nich jak najmniej, możesz wypróbować programowanie funkcjonalne, co jest niesamowitym doświadczeniem, gdy zaczynasz je rozumieć i prawdopodobnie uczyni cię lepszym programistą. </propaganda>
phipsgabler
3
Jesteś moim bogiem, a Twoja propaganda jest moim chlebem powszednim. Jednak próbowałem zastosować to na krotce: (train["pred_idx_cos"],train["target"]).apply(lambda x,y: get_result(x, y))i wygląda na to, że nie działa. Proszę, ocal moją duszę od mgły programowania proceduralnego
Revolucion dla Moniki,
@RevolucionforMonica Trochę spóźniona odpowiedź, ale oto przykład kodu Python 3 REPL pokazujący,
Mass Dot Net
11

Uważam, że bind zawsze próbuje wysłać parametr zdarzenia. Próbować:

self.entry_1.bind("<Return>", lambda event: self.calculate(self.buttonOut_1.grid_info(), 1))

Akceptujesz parametr i nigdy go nie używasz.

Demosthenex
źródło
omg, pracowałem nad tym przez tak długi czas, a potem otrzymuję działającą odpowiedź w ciągu 1 minuty ... Przy okazji, wiesz, dlaczego sprawy idą przed dwukropkami?
Talisin
2
Ponieważ są to parametry funkcyjne .
phipsgabler
3
Możesz także spróbować „event = None”, aby nadać mu wartość domyślną, a następnie funkcja może być użyta do wiązania i przycisku.
Demosthenex
5

Dlaczego musisz podać oba xi yprzed :?

Ponieważ jest to definicja funkcji i musi wiedzieć, jakie parametry funkcja akceptuje iw jakiej kolejności. Nie może po prostu spojrzeć na wyrażenie i użyć w nim nazw zmiennych, ponieważ niektóre z tych nazw mogą chcieć użyć istniejących lokalnych lub globalnych wartości zmiennych, a nawet gdyby to zrobił, nie wiedziałby, w jakiej kolejności powinien spodziewać się ich.

Twój komunikat o błędzie oznacza, że ​​Tk wywołuje twoją lambdę z jednym argumentem, podczas gdy twoja lambda jest napisana tak, aby nie akceptowała żadnych argumentów. Jeśli nie potrzebujesz argumentu, zaakceptuj go i nie używaj go. ( Demosthenex ma kod , wysłałbym go, ale zostałem pobity).

kindall
źródło
Dziękuję za wyjaśnienie. Myślę, że w końcu się nad tym zastanawiam.
Talisin
3

Dlaczego musisz podać „x” i „y” przed „:”?

Właściwie możesz w niektórych sytuacjach (kiedy masz tylko jeden argument) nie wstawiać x i y przed ":".

>>> flist = []
>>> for i in range(3):
...     flist.append(lambda : i)

ale i w lambdzie będzie związane z imieniem, więc

>>> flist[0]()
2
>>> flist[2]()
2
>>>

różni się od tego, czego możesz chcieć.

AlbertoAndreotti
źródło