Lambda in Python verstehen und es verwenden, um mehrere Argumente zu übergeben

88

Nachdem ich alles gelesen habe, was ich auf Lambda finden kann, verstehe ich immer noch nicht, wie ich es dazu bringen soll, das zu tun, was ich will.

Jeder benutzt das Beispiel:

lambda x, y : x + y

Warum müssen Sie beide xund yvor dem :angeben? Wie kann man auch mehrere Argumente zurückgeben?

beispielsweise:

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

Das funktioniert gut. Der folgende Code funktioniert jedoch nicht:

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

Es ergibt sich der Fehler:

TypeError: () akzeptiert keine Argumente (1 angegeben)

Talisin
quelle

Antworten:

132

Warum müssen Sie vor dem ':' sowohl 'x' als auch 'y' angeben?

Weil ein Lambda (konzeptionell) dasselbe ist wie eine Funktion, nur inline geschrieben. Ihr Beispiel entspricht

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

nur ohne es an einen Namen wie zu binden f.

Wie kann man auch mehrere Argumente zurückgeben?

Genauso wie bei einer Funktion. Am besten geben Sie ein Tupel zurück:

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

Oder eine Liste oder eine Klasse oder was auch immer.

Die Sache mit self.entry_1.bindsollte von Demosthenex beantwortet werden.

phipsgabler
quelle
2
Um wirklich das geringste aus ihnen herauszuholen, könnten Sie eine funktionale Programmierung ausprobieren, was eine großartige Erfahrung ist, wenn Sie anfangen, es zu verstehen, und Sie wahrscheinlich zu einem besseren Programmierer machen wird. </ Propaganda>
Phipsgabler
3
Du bist mein Gott und deine Propaganda ist mein tägliches Brot. Ich habe jedoch versucht, es auf ein Tupel anzuwenden: (train["pred_idx_cos"],train["target"]).apply(lambda x,y: get_result(x, y))und es scheint, dass es nicht funktioniert. Bitte rette meine Seele vor dem Nebel der prozeduralen Programmierung
Revolucion für Monica
@RevolucionforMonica Eine etwas späte Antwort, aber hier ist ein Python 3 REPL-Codebeispiel dafür: repl.it/@foobar123/ScarceWhimsicalMainframe
Mass Dot Net
11

Ich glaube, bind versucht immer, einen Ereignisparameter zu senden. Versuchen:

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

Sie akzeptieren den Parameter und verwenden ihn niemals.

Demosthenex
quelle
omg, ich habe so lange daran gearbeitet und dann bekomme ich in 1 Minute eine funktionierende Antwort ... Übrigens, weißt du, warum die Dinge vor den Doppelpunkten laufen?
Talisin
2
Weil sie fuction Parameter .
Phipsgabler
3
Sie können auch "event = None" versuchen, um einen Standardwert festzulegen. Anschließend kann die Funktion zum Binden und für die Schaltfläche verwendet werden.
Demosthenex
5

Warum müssen Sie beide xund yvor dem :angeben?

Weil es sich um eine Funktionsdefinition handelt und bekannt sein muss, welche Parameter die Funktion in welcher Reihenfolge akzeptiert. Es kann nicht nur den Ausdruck betrachten und die Variablennamen darin verwenden, da einige dieser Namen möglicherweise vorhandene lokale oder globale Variablenwerte verwenden möchten, und selbst wenn dies der Fall wäre, würde es nicht wissen, in welcher Reihenfolge sollte erwarten, sie zu bekommen.

Ihre Fehlermeldung bedeutet, dass Tk Ihr Lambda mit einem Argument aufruft, während Ihr Lambda so geschrieben ist, dass es keine Argumente akzeptiert. Wenn Sie das Argument nicht benötigen, akzeptieren Sie einfach eines und verwenden Sie es nicht. ( Demosthenex hat den Code , ich hätte ihn gepostet, wurde aber geschlagen.)

irgendwie
quelle
Danke für die Erklärung. Ich denke, ich werde mich endlich darum kümmern.
Talisin
3

Warum müssen Sie vor dem ':' sowohl 'x' als auch 'y' angeben?

In einigen Situationen (wenn Sie nur ein Argument haben) können Sie x und y nicht vor ":" setzen.

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

aber das i im Lambda wird namentlich gebunden sein, also

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

anders als Sie vielleicht wollen.

AlbertoAndreotti
quelle