Part 1 of our homage to John Wick 2, in theaters February 10.
Director Jon Chang
Talent Nea Dune
Shutter Stephen Ciuccoli and Jon Chang
Garment Suit Marika Soderlund-Robinson
seen from Pakistan
seen from United States
seen from Iraq
seen from Germany
seen from China
seen from Canada
seen from Pakistan

seen from Sweden

seen from United States
seen from Türkiye

seen from Romania

seen from Canada
seen from China
seen from Greece

seen from United States

seen from China
seen from United States

seen from Romania

seen from United States
seen from Türkiye
Part 1 of our homage to John Wick 2, in theaters February 10.
Director Jon Chang
Talent Nea Dune
Shutter Stephen Ciuccoli and Jon Chang
Garment Suit Marika Soderlund-Robinson
Learn about the various types of variable scope in Python like Global, Local, built in and enclosed with syntax and example.
Scope of variables when function in function in JavaScript
Scope of variables when function in function in JavaScript
Variables in a function only affect the function in JavaScript, can’t be used in another functions, as we know. But how about the scope of variable when function in function. (more…)
View On WordPress
Interesting article about variable scope, plus a look at the strange behaviour of this keyword.
I'm an idiot
Just in case anyone noticed, my recently created "inspiration bot" was repeatedly posting the same quote every day. This is because I'm and idiot who doesn't understand variable scope, or at least I was when I wrote it the bots code. It should now work better(I hope, only time will tell). Anyway, back to the usual schedule etc.
Python lambdas and variable scope
The issue
Recently, a colleague posted the following code snippet and asked for an explanation of why it didn't work as they expected:
x = [] for i in range(1, 10): x.append(lambda z: "%d" % i + z) print(list(x[i]("banzaii") for i in range(0, 9)))
which results in:
['9banzaii', '9banzaii', '9banzaii', '9banzaii', '9banzaii', '9banzaii', '9banzaii', '9banzaii', '9banzaii']
instead of the expected:
['1banzaii', '2banzaii', '3banzaii', '4banzaii', '5banzaii', '6banzaii', '7banzaii', '8banzaii', '9banzaii']
The explanation
The key is that the variable i is outside of the scope of the created lambda. Only the variable z is in the lambda scope. Essentially it would be like writing:
x=[] def fn(z): return "%d" % i + z for i in range(1, 10): x.append(fn)
which makes it a lot more obvious what is going on. The global variable i is used each time the function is actually called--which is after the for loop is executed and i is now 9.
The fix
The fix is simple: make sure that i is in the scope of the function that is appended to array x.
Solution 1: using a closure
def makefunc(i): def inner(z): return "%d" % i + z return inner x=[] for i in range(1, 10): x.append(makefunc(i))
In this example, a closure around the function inner passes i into the returned function's scope.
Solution 2: using lambda to create an anonymous closure
x=[] for i in range(1, 10): x.append((lambda n: lambda z: "%d" % n + z)(i))
Here, we are appending the result of calling a lambda function with the argument i which returns a lambda that uses that value. This is exactly equivalent to the previous example, but for people who like one-liners. :)
Solution 3: using a lambda with a default argument
x=[] for i in range(1, 10): x.append(lambda z, n=i: "%d" % n + z)
This solution ensures that we are using a variable n that is in the lambda's scope and is initialized by default to i. A possible issue with this solution is if the caller of the function in x[i] passes an additional argument which overrides the default value of n. With the previous solutions, this bug would raise a TypeError exception instead of running successfully with (most likely) unintended results.