Compreender lambda em python e usá-lo para passar vários argumentos

91

Depois de ler tudo que pude encontrar sobre lambda, ainda não entendi como fazer o que eu quero.

Todos usam o exemplo:

lambda x, y : x + y

Por que você precisa indicar xe yantes de :? Além disso, como você faz com que ele retorne vários argumentos?

por exemplo:

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

Isso funciona muito bem. Mas o código a seguir não:

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

Isso produz o erro:

TypeError: () não aceita argumentos (1 fornecido)

Talisin
fonte

Respostas:

138

Por que você precisa indicar 'x' e 'y' antes de ':'?

Porque um lambda é (conceitualmente) o mesmo que uma função, apenas escrito inline. Seu exemplo é equivalente a

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

apenas sem vinculá-lo a um nome como f.

Além disso, como fazer com que ele retorne vários argumentos?

Da mesma forma que acontece com uma função. De preferência, você retorna uma tupla:

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

Ou uma lista, ou uma aula, ou o que for.

A coisa com self.entry_1.binddeve ser respondida por Demosthenex.

phipsgabler
fonte
2
Para realmente obter o mínimo deles, você pode tentar alguma programação funcional, o que é uma experiência incrível quando você começa a entendê-la, e provavelmente o tornará um programador melhor. </propaganda>
phipsgabler
3
Você é meu deus e sua propaganda é meu pão de cada dia. Mesmo assim, tentei aplicar em uma tupla: (train["pred_idx_cos"],train["target"]).apply(lambda x,y: get_result(x, y))e parece que não funciona. Por favor, salve minha alma da névoa da programação processual
Revolucion for Monica
@RevolucionforMonica Uma resposta um pouco tardia, mas aqui está um exemplo de código REPL do Python 3 de como fazer isso: repl.it/@foobar123/ScarceWhimsicalMainframe
Mass Dot Net
11

Acredito que o bind sempre tenta enviar um parâmetro de evento. Experimentar:

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

Você aceita o parâmetro e nunca o usa.

Demosthenex
fonte
omg, eu estive trabalhando nisso por tanto tempo e então eu recebo uma resposta de trabalho em 1 minuto bem ... A propósito, você sabe por que as coisas ficam na frente dos dois pontos?
Talisin
2
Porque são parâmetros de função .
phipsgabler
3
Você também pode tentar "event = None" para dar a ele um valor padrão, então a função pode ser usada para bind e o botão.
Demosthenex
5

Por que você precisa indicar xe yantes de :?

Porque é uma definição de função e precisa saber quais parâmetros a função aceita e em que ordem. Ele não pode apenas olhar para a expressão e usar os nomes das variáveis ​​nela, porque alguns desses nomes você pode querer usar para os valores das variáveis ​​locais ou globais existentes, e mesmo se fizesse isso, não saberia em que ordem deve esperar obtê-los.

Sua mensagem de erro significa que Tk está chamando seu lambda com um argumento, enquanto seu lambda é escrito para não aceitar nenhum argumento. Se você não precisa do argumento, aceite um e não o use. ( Demosthenex tem o código , eu o teria postado, mas fui derrotado).

kindall
fonte
Obrigada pelo esclarecimento. Acho que estou finalmente entendendo isso.
Talisin
3

Por que você precisa indicar 'x' e 'y' antes de ':'?

Você poderia, na verdade, em algumas situações (quando você tem apenas um argumento), não colocar xey antes de ":".

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

mas o i no lambda será vinculado pelo nome, então,

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

diferente do que você pode querer.

AlbertoAndreotti
fonte