Skip to content Skip to sidebar Skip to footer

Capturing Value Instead Of Reference In Lambdas

I was slightly surprised by this example given by Eli Bendersky (http://eli.thegreenplace.net/2015/the-scope-of-index-variables-in-pythons-for-loops/) >>> def foo(): ...

Solution 1:

Default param is an another way to catch a value:

lst.append(lambda i=i: i)

Solution 2:

It appears that the reason that this works is that when i is provided to the outer lambda, the outer lambda creates a scope and dereferences i, setting a to i. Then, the inner lambda, which is returned, holds a reference to a.

Is this a correct explanation?

I don't like it. Python does not pass by reference:

def func(x):
    x = 10

num = 3func(num)print num  #=>3

As a result, the terms reference and dereference are not in the python lexicon. Or, you could say that python always dereferences a function argument before assigning it to a parameter variable--so your explanation doesn't really explain anything.

The reason the example works is because of the rule:

A function's local variables are destroyed after it finishes executing.

A function's local variables include its parameter variables. Every time the outer lambda executes, a new 'a' variable is created. As a result, each inner lambda closes over a different 'a' variable.

You did allude to that state of affairs:

the outer lambda creates a scope

...

the lambda is capturing a reference to i rather than i's value.

Or, as I like to phrase it.

A closure closes over variables--not values.

That is the way closures work in most languages(an exception being perl, where closures close over values).

Solution 3:

Yes, it looks correct. If you are familiar with javascript and know closures, you will notice how similar they are.

If not - there is a nice explanation on SO regarding JS closures and the concept is absolutely the same (as well as the explanation and even wrong and correct usage).

Post a Comment for "Capturing Value Instead Of Reference In Lambdas"