Comprendre lambda en python et l'utiliser pour passer plusieurs arguments

90

Après avoir lu tout ce que je peux trouver sur lambda, je ne comprends toujours pas comment le faire faire ce que je veux.

Tout le monde utilise l'exemple:

lambda x, y : x + y

Pourquoi devez-vous indiquer les deux xet yavant le :? Aussi comment faire renvoyer plusieurs arguments?

par exemple:

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

Cela fonctionne très bien. Mais le code suivant ne le fait pas:

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

Cela donne l'erreur:

TypeError: () ne prend aucun argument (1 donné)

Talisin
la source

Réponses:

136

Pourquoi avez-vous besoin d'indiquer à la fois «x» et «y» avant le «:»?

Parce qu'un lambda est (conceptuellement) identique à une fonction, juste écrit en ligne. Votre exemple équivaut à

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

juste sans le lier à un nom comme f.

Aussi comment faire renvoyer plusieurs arguments?

De la même manière que pour une fonction. De préférence, vous retournez un tuple:

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

Ou une liste, ou une classe, ou autre.

La chose avec self.entry_1.binddevrait être répondu par Demosthenex.

phipsgabler
la source
2
Pour vraiment en tirer le moins possible, vous pouvez essayer une programmation fonctionnelle, ce qui est une expérience formidable lorsque vous commencez à la comprendre, et fera probablement de vous un meilleur programmeur. </propaganda>
phipsgabler
3
Tu es mon dieu et ta propagande est mon pain quotidien. Pourtant, j'ai essayé de l'appliquer sur un tuple: (train["pred_idx_cos"],train["target"]).apply(lambda x,y: get_result(x, y))et il semble que cela ne fonctionne pas. S'il vous plaît, sauvez mon âme du brouillard de la programmation procédurale
Revolucion for Monica
@RevolucionforMonica Une réponse un peu tardive, mais voici un exemple de code Python 3 REPL de la façon de le faire: repl.it/@foobar123/ScarceWhimsicalMainframe
Mass Dot Net
11

Je crois que bind essaie toujours d'envoyer un paramètre d'événement. Essayer:

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

Vous acceptez le paramètre et ne l'utilisez jamais.

Démosthénex
la source
omg, je travaillais là-dessus depuis si longtemps et puis j'obtiens une réponse de travail en 1 minute à plat ... Btw, savez-vous pourquoi les choses se passent devant les deux-points?
Talisin
2
Parce que ce sont des paramètres de fonction .
phipsgabler
3
Vous pouvez également essayer "event = None" pour lui donner une valeur par défaut, alors la fonction peut être utilisée pour bind et le bouton.
Demosthenex
5

Pourquoi devez-vous indiquer les deux xet yavant le :?

Parce que c'est une définition de fonction et qu'elle a besoin de savoir quels paramètres la fonction accepte, et dans quel ordre. Il ne peut pas simplement regarder l'expression et utiliser les noms de variables, parce que certains de ces noms pour lesquels vous voudrez peut-être utiliser des valeurs de variables locales ou globales existantes, et même s'il le faisait, il ne saurait dans quel ordre devrait s'attendre à les obtenir.

Votre message d'erreur signifie que Tk appelle votre lambda avec un argument, tandis que votre lambda est écrit pour n'accepter aucun argument. Si vous n'avez pas besoin de l'argument, acceptez-en un et ne l'utilisez pas. ( Demosthenex a le code , je l'aurais posté mais j'ai été battu.)

kindall
la source
Merci pour l'explication. Je pense que je suis enfin en train de comprendre ça.
Talisin
3

Pourquoi avez-vous besoin d'indiquer à la fois «x» et «y» avant le «:»?

Vous pouvez en fait dans certaines situations (lorsque vous n'avez qu'un seul argument) ne pas mettre les x et y avant ":".

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

mais le i dans le lambda sera lié par son nom, donc,

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

différent de ce que vous pourriez souhaiter.

AlbertoAndreotti
la source