ламбда в python с допълнителна непредадена променлива

Аз съм нов в скриптовете на python. Объркан съм как ламбда интерпретира предадените променливи, както в примера по-долу.

def create_multipliers():
  return [lambda x : i * x for i in range(5)]

for multiplier in create_multipliers():
  print multiplier(2),

връща 8 8 8 8 8

Виждам, че ламбда приема само един аргумент (т.е. 'x').

Как интерпретира x и i в create_multipliers? Освен това какво означава множител (2)?

Моля помогнете

Също и с примера по-долу

def make_incrementor (n): return lambda x: x + n
print make_incrementor(22)(33)

върнати 55

Как функцията lambda/make_incrementor решава кое е 'x' и 'n'?


person anudeep    schedule 05.08.2016    source източник
comment
niemmi е написал отличен отговор, въпреки че бих ви препоръчал също да прочетете Защо lambdas са готини на същия този сайт, аз още не сте го направили.   -  person AdrienW    schedule 05.08.2016


Отговори (1)


Първата част от кода създава списък от ламбда, всяка от които приема един аргумент x и го умножава с i. Имайте предвид, че всяка ламбда е обвързана с променлива i не текущата му стойност. Тъй като стойността на i след разбирането на списъка е 4, всяка ламбда ще върне x * 4:

>>> def create_multipliers():
...     return [lambda x: i * x for i in range(5)]
...
>>> l = create_multipliers()
>>> l[0](1)
4
>>> l[4](1)
4
>>> l[4]('foobar')
'foobarfoobarfoobarfoobar'

След това цикълът ще изпълни всяка ламбда с параметър 2 и ще отпечата резултатите на същия ред. Тъй като има 5 ламбда и 4 * 2 е 8, получавате резултата, който виждате. , след израза print ще доведе до отпечатване на изхода на същия ред:

>>> for multiplier in l:
...     print multiplier(2),
...
8 8 8 8 8

make_incrementor работи на същия принцип. Връща ламбда, която приема единичен аргумент x, който се "решава", когато се извиква ламбда. След това ще върне x + n, където n е стойността, предадена на make_incrementor:

>>> def make_incrementor(n):
...     return lambda x: x + n
...
>>> inc = make_incrementor(2) # n is "decided" here
>>> inc(3)                    # and x here
5

АКТУАЛИЗАЦИЯ Пример с вложени функции:

>>> def make_incrementor(n):
...     def nested(x):
...         return x + n
...     return nested
...
>>> inc = make_incrementor(2)
>>> inc(3)
5
person niemmi    schedule 05.08.2016
comment
Как ламбда приема 'x' като аргумент. Как се решава? (в примера make_incrementor) Това ли е функционалността на ламбда? Може ли това нещо да се направи в нормални вложени функции? - person anudeep; 05.08.2016
comment
@deeps: x е само името на аргумента, можете също да го наименувате на y или foobar точно както при други функции. Стойността, разбира се, се определя от момента на извикването. Бихте могли да приложите горните примери също толкова лесно с вложени функции, просто ще са необходими още няколко реда. - person niemmi; 05.08.2016
comment
:лошо, вместо да спомена 33-те, аз го споменах като "x". Въпросът ми беше (може да е глупав, но ме побърква) как така ламбда приема 3 от make_incrementor(2)(3) като свой 'x'. Това ли е специалността на ламбда? или някой го инструктира? Също така се опитах с вложени функции да внедря желаната функционалност, но не мога да го направя. - person anudeep; 05.08.2016
comment
@deeps: Добавен пример с вложена функция. make_incrementor приема n (2 в пример) като параметър, който вложената функция/ламбда използва по-късно, когато се изпълни. make_incrementor връща вложената функция/ламбда, която след това изисква параметър x (3 в примера). Имайте предвид, че в примера върнатата функция/ламбда е присвоена на inc, която се извиква на следващия ред. Можех също така да свържа обажданията с make_incrementor(2)(3) и да постигна същия резултат. - person niemmi; 05.08.2016
comment
Наистина беше страхотно!! - person anudeep; 05.08.2016