Понимание лямбда-выражения в python и его использование для передачи нескольких аргументов

91

Прочитав все, что я могу найти о лямбде, я все еще не понимаю, как заставить его делать то, что я хочу.

Все используют пример:

lambda x, y : x + y

Зачем вам нужно , чтобы государства как xи yпрежде , чем :? Также как заставить его возвращать несколько аргументов?

например:

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

Это прекрасно работает. Но следующий код этого не делает:

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

Это дает ошибку:

TypeError: () не принимает аргументов (1 дан)

Талисин
источник

Ответы:

138

Почему вам нужно указывать "x" и "y" перед ":"?

Потому что лямбда (концептуально) то же самое, что и функция, только встроенная. Ваш пример эквивалентен

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

просто без привязки к имени вроде f.

Также как сделать так, чтобы он возвращал несколько аргументов?

Так же, как и с функцией. Желательно, чтобы вы возвращали кортеж:

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

Или список, или класс, или что-то еще.

На вопрос с self.entry_1.bindдолжен ответить Demosthenex.

phipsgabler
источник
2
Чтобы получить от них хоть немного, вы можете попробовать функциональное программирование, что является потрясающим опытом, когда вы начинаете понимать его, и, вероятно, сделает вас лучшим программистом. </propaganda>
phipsgabler
3
Ты мой бог, а твоя пропаганда - мой хлеб насущный. Тем не менее, я попытался применить его к кортежу: (train["pred_idx_cos"],train["target"]).apply(lambda x,y: get_result(x, y))и, похоже, это не сработало. Пожалуйста, спасите мою душу от тумана процедурного программирования
Revolucion для Моники
@RevolucionforMonica Немного запоздалый ответ, но вот пример кода REPL Python 3, как это сделать: repl.it/@foobar123/ScarceWhimsicalMainframe
Mass Dot Net
11

Я считаю, что bind всегда пытается отправить параметр события. Пытаться:

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

Вы принимаете параметр и никогда его не используете.

Демостенекс
источник
Боже мой, я так долго работал над этим, а потом я получил рабочий ответ через 1 минуту ... Кстати, ты знаешь, почему все идет впереди двоеточия?
Talisin
2
Потому что это параметры функции .
phipsgabler
3
Вы также можете попробовать «event = None», чтобы присвоить ему значение по умолчанию, тогда функцию можно будет использовать для привязки и кнопки.
Demosthenex
5

Зачем нужно указывать оба x и yпрежде , чем :?

Потому что это определение функции, и ему нужно знать, какие параметры принимает функция и в каком порядке. Он не может просто смотреть на выражение и использовать в нем имена переменных, потому что для некоторых из этих имен вы, возможно, захотите использовать существующие значения локальных или глобальных переменных, и даже если бы он это сделал, он не знал бы, в каком порядке он следует ожидать их получить.

Ваше сообщение об ошибке означает, что Tk вызывает вашу лямбду с одним аргументом, в то время как ваша лямбда написана так, что не принимает аргументов. Если аргумент вам не нужен, просто примите его и не используйте. (У Demosthenex есть код , я бы выложил его, но меня опередили.)

любезный
источник
Спасибо за объяснение. Думаю, я наконец-то обдумал это.
Talisin
3

Почему вам нужно указывать "x" и "y" перед ":"?

На самом деле вы могли бы в некоторых ситуациях (когда у вас только один аргумент) не ставить x и y перед ":".

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

но i в лямбде будет привязан к имени, поэтому

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

отличается от того, что вы хотите.

АльбертоАндреотти
источник