3

I am new to python scripting. I am confused how lambda interprets variables passed as in below example.

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

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

returns 8 8 8 8 8

I see that lambda accepts only one argument (i.e 'x').

How does it interpret x and i in create_multipliers? Also what does multiplier(2) mean?

Please help

Also with the below example

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

returned 55

How does the lambda/make_incrementor function decide which is 'x' and 'n'?

anudeep
  • 415
  • 6
  • 19
  • [niemmi](http://stackoverflow.com/users/5043793/niemmi) has written an excellent answer, though I'd also recommend you to read [Why `lambda`s are cool](http://stackoverflow.com/q/890128/5018771) on this very site I you haven't already. – AdrienW Aug 05 '16 at 10:57

1 Answers1

2

The first part of code creates a list of lambdas which each take single argument x and multiplies it with i. Note that each lambda is bound to variable i not its' current value. Since the value of i after the list comprehension is 4 each lambda will return 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'

The loop will then execute each lambda with parameter 2 and print the results to same line. Since there are 5 lambdas and 4 * 2 is 8 you get the output that you see. , after the print statement will result the output to be printed on the same line:

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

make_incrementor works with same principle. It returns a lambda that takes single argument x which is "decided" when lambda is called. It will then return x + n where n is the value passed to 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

UPDATE Example with nested functions:

>>> def make_incrementor(n):
...     def nested(x):
...         return x + n
...     return nested
...
>>> inc = make_incrementor(2)
>>> inc(3)
5
niemmi
  • 17,113
  • 7
  • 35
  • 42
  • How does the lambda takes 'x' as the argument.How is it decided?(in the make_incrementor example) Is that the functionality of lambda? Can that thing be done in normal nested functions? – anudeep Aug 05 '16 at 13:46
  • @deeps: `x` is just the name of the argument, you could as well name it to `y` or `foobar` just like with other functions. The value is of course decided by the time it is called. You could implement the above examples just as easily with nested functions, it would just require couple more lines. – niemmi Aug 05 '16 at 13:53
  • :my bad instead of mentioning the 33 i mentioned it as 'x'. My question was(might be stupid but its driving me nuts) how come does the lambda take the 3 from make_incrementor(2)(3) as its 'x'.Is that the speciality of lambda? or someone instructs it to? I also tried with nested functions to implement the desired functionality , I am unable to do so. – anudeep Aug 05 '16 at 13:58
  • @deeps: Added example with nested function. `make_incrementor` takes `n` (`2` in example) as a parameter which nested function/lambda uses later when it's executed. `make_incrementor` returns the nested function/lambda that then requires a parameter `x` (`3` in example). Note that in the example returned function/lambda is assigned to `inc` that is called on the following line. I could just as well have chained the calls with `make_incrementor(2)(3)` and achieve the same result. – niemmi Aug 05 '16 at 14:08
  • It was indeed great!! – anudeep Aug 05 '16 at 14:14