you may force the capture of a variable using an argument with a default value:

>>> for i in [0,1,2,3]:
...    adders[i]=lambda a,i=i: i+a  # note the dummy parameter with a default value
...
>>> print( adders1 )
4

the idea is to declare a parameter (cleverly named i) and give it a default value of the variable you want to capture (the value of i)

Answer from Adrien Plisson on Stack Overflow
Top answer
1 of 8
339

you may force the capture of a variable using an argument with a default value:

>>> for i in [0,1,2,3]:
...    adders[i]=lambda a,i=i: i+a  # note the dummy parameter with a default value
...
>>> print( adders1 )
4

the idea is to declare a parameter (cleverly named i) and give it a default value of the variable you want to capture (the value of i)

2 of 8
239

What do the closures capture exactly?

Closures in Python use lexical scoping: they remember the name and scope of the closed-over variable where it is created. However, they are still late binding: the name is looked up when the code in the closure is used, not when the closure is created. Since all the functions in your example are created in the same scope and use the same variable name, they always refer to the same variable.

There are at least two ways to get early binding instead:

  1. The most concise, but not strictly equivalent way is the one recommended by Adrien Plisson. Create a lambda with an extra argument, and set the extra argument's default value to the object you want preserved.

  2. More verbosely but also more robustly, we can create a new scope for each created lambda:

    >>> adders = [0,1,2,3]
    >>> for i in [0,1,2,3]:
    ...     adders[i] = (lambda b: lambda a: b + a)(i)
    ...     
    >>> adders1
    4
    >>> adders2
    5
    

    The scope here is created using a new function (another lambda, for brevity), which binds its argument, and passing the value you want to bind as the argument. In real code, though, you most likely will have an ordinary function instead of the lambda to create the new scope:

    def createAdder(x):
        return lambda y: y + x
    adders = [createAdder(i) for i in range(4)]
    
๐ŸŒ
Python.org
discuss.python.org โ€บ ideas
Make lambdas proper closures - Ideas - Discussions on Python.org
September 10, 2021 - Does nobody find this behavior bizarre? Is it actually useful for anything and does anybody rely on it? >>> larr = [lambda: i for i in range(10)] >>> iarr = [l() for l in larr] >>> iarr [9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
๐ŸŒ
Plain English
python.plainenglish.io โ€บ python-pitfalls-with-variable-capture-dcfc113f39b7
Python: Pitfalls With Variable Capture | by bob kerner | Python in Plain English
May 13, 2023 - Consider the following code that creates a list of lambdas, each of which prints a value of 2 raised to the power of some number: #------------------------------------------------------------------- # Test: Capturing with lambdasdef make_function_list(): result = [] for i in range(10): result.append(lambda: 2**i) return resultprint([f() for f in make_function_list()])#------------------------------------------------------------------- # Output# [512, 512, 512, 512, 512, 512, 512, 512, 512, 512]
๐ŸŒ
Python.org
discuss.python.org โ€บ python help
Is default argument value the capture syntax in lambda - Python Help - Discussions on Python.org
March 11, 2022 - The other languages like C++, Swift, Rust use special syntax for capture. I just test the following snippet. And find out if the default argument value is a variable for lambda, it is a capture. I think this is pretty simple and smart. Please correct me if I was wrong.
๐ŸŒ
Amazon Web Services
docs.aws.amazon.com โ€บ aws lambda โ€บ developer guide โ€บ building lambda functions with python โ€บ log and monitor python lambda functions
Log and monitor Python Lambda functions - AWS Lambda
Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverless best practices and increase developer velocity. The Logger utility provides a Lambda optimized logger which includes additional information about function context across all your functions with output structured as JSON. Use this utility to do the following: Capture key fields from the Lambda context, cold start and structures logging output as JSON
Find elsewhere
๐ŸŒ
Reddit
reddit.com โ€บ r/programminglanguages โ€บ python closures are capturing by reference, should this be normal in a language?
r/ProgrammingLanguages on Reddit: Python closures are capturing by reference, should this be normal in a language?
June 7, 2019 - This is par for the course. Python has been intentionally moving away from functional paradigms in favor of readability; i.e. [x for x in xs if x > 0] is easier to read in Python than filter(lambda x: x > 0: x, xs).
๐ŸŒ
Real Python
realpython.com โ€บ python-lambda
How to Use Python Lambda Functions โ€“ Real Python
December 1, 2023 - On line 5, inner_func() captures x and y because it has access to its embedding environment, such that upon invocation of the closure, it is able to operate on the two free variables x and y. Similarly, a lambda can also be a closure. Hereโ€™s the same example with a Python lambda function:
๐ŸŒ
Sololearn
sololearn.com โ€บ en โ€บ Discuss โ€บ 3039831 โ€บ solved-on-pythons-lambda-and-closures
[Solved] on Python's lambda and closures. | Sololearn: Learn to code for FREE!
May 30, 2022 - I have to say I really love python, it is simple and amazing :] ... it's like for each iteration i list_i= [2, 2, 2] because the loop is executed inside the comprehension first for each lambda, giving a single value(last one in range as Sandeep said in his first post), and then iterate x*i over list_i, like mapping, as far as I understand.
๐ŸŒ
Real Python
realpython.com โ€บ python-closure
Python Closures: Common Use Cases and Examples โ€“ Real Python
September 12, 2024 - >>> greeter = outer_func() >>> greeter() Hello, Pythonista! In this modified version of outer_func(), you use a lambda function to build the closure, which works like the original one.
๐ŸŒ
Louisabraham
louisabraham.github.io โ€บ articles โ€บ python-lambda-closures.html
On Python's lambda and closures
July 25, 2017 - And in this closure, all the lambda functions take the same value of i as it changes. Note that if you use Python 2, the variable i is even accessible from the global context as the list comprehension does not define any closure (but generator expressions do, so itโ€™ll work with tuples, sets or dictionaries).
๐ŸŒ
Cppreference
en.cppreference.com โ€บ w โ€บ cpp โ€บ language โ€บ lambda.html
Lambda expressions (since C++11) - cppreference.com
Constructs a closure (an unnamed function object capable of capturing variables in scope). ... A variable __func__ is implicitly defined at the beginning of body, with semantics as described here. The lambda expression is a prvalue expression of unique unnamed non-union non-aggregate class ...
๐ŸŒ
GitHub
gist.github.com โ€บ gisbi-kim โ€บ 2e5648225cc118fc72ac933ef63c2d64
Why Lambda in a Loop is a Code Smell in python? Also it happens in c++? ยท GitHub
In Python, using a lambda function in a loop can lead to unexpected behavior due to late binding. This means the lambda function captures the variable, not the value.
๐ŸŒ
LabEx
labex.io โ€บ tutorials โ€บ python-how-to-capture-variables-in-closures-420182
How to capture variables in closures | LabEx
graph TD A[Outer Function] --> B[Inner Function] A --> C[Captured Variables] B --> D[Access Captured Variables] ... def create_counter(): count = 0 def counter(): nonlocal count count += 1 return count return counter ## Using the closure my_counter = create_counter() print(my_counter()) ## 1 print(my_counter()) ## 2 ... By mastering closures, Python developers can write more flexible and elegant code.
๐ŸŒ
Python
bugs.python.org โ€บ issue13652
Issue 13652: Creating lambda functions in a loop has unexpected results when resolving variables used as arguments - Python tracker
December 22, 2011 - This issue tracker has been migrated to GitHub, and is currently read-only. For more information, see the GitHub FAQs in the Python's Developer Guide ยท This issue has been migrated to GitHub: https://github.com/python/cpython/issues/57861
๐ŸŒ
Python Reference
python-reference.readthedocs.io โ€บ en โ€บ latest โ€บ docs โ€บ operators โ€บ lambda.html
lambda โ€” Python Reference (The Right Way) 0.1 documentation
>>> # this is a code snippet from a Tkinter gui app >>> # in this case lambda is quite convenient >>> self.btn_cancel = Button(self.progress_container, text='Cancel', >>> command=lambda: subprocess.call('taskkill /f /im uberzip.exe', >>> shell=True))
๐ŸŒ
Dataquest
dataquest.io โ€บ blog โ€บ tutorial-lambda-functions-in-python
Tutorial: Lambda Functions in Python
March 6, 2023 - We use a lambda function to evaluate only one short expression (ideally, a single-line) and only once, meaning that we aren't going to apply this function later. Usually, we pass a lambda function as an argument to a higher-order function (the one that takes in other functions as arguments), such as Python built-in functions like filter(), map(), or reduce().
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ c++ โ€บ lambda-capture-clause-in-cpp
Lambda Capture Clause in C++ - GeeksforGeeks
Lambda expressions were introduced ... features of lambdas is the capture clause, which controls how variables from the surrounding scope are accessed inside the lambda body....
Published ย  February 5, 2024