лямбда в питоне с дополнительной непереданной переменной

Я новичок в написании сценариев на питоне. Я запутался, как лямбда интерпретирует переменные, переданные, как в приведенном ниже примере.

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 и 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 написал отличный ответ, хотя я также рекомендую вам прочитать Почему lambda это круто на этом самом сайте, которого вы еще не видели.   -  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, я упомянул это как «х». Мой вопрос был (может быть, глупым, но это сводит меня с ума), почему лямбда берет 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