Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda in loop stored in list, prints only the last loops evaluated value not different values from all loop iterations [duplicate]

Tags:

python

lambda

I have a problem with lambdas in a loop. It is hard to explain the problem so I will show it in a short example:

class TestObj():
    def __init__(self, value):
        self.value = value

lambdas = []
values_list = [10, 1]
for ele in values_list:
    foo = TestObj(ele)
    lambdas.append(lambda: foo.value > 5)

print([single_lambda() for single_lambda in lambdas])

as a result of print I get:

[False, False]

Despite I would expect [True, False]. Could you tell me why it does not work? and how Could I get the result that I expected? I only add that lambdas in a loop are required in my code to define formulas(those formulas are a lot and can be much more complex). Those formulas are defined in one place in the application and executed after many lines below the definition. I would be grateful for your help.

like image 678
Isel Avatar asked Jan 17 '26 08:01

Isel


1 Answers

Lambdas are evaluated when they are executed.

They are executed when you print them. The only known foo at that time is the one from the last loop. So TestObj(1) is printed twice.

You can verify this by changing your lambda to:

lambdas.append(lambda: id(foo))   # will print the id() of the used foo

You need to "early" bind the foo from the loop to the lambda:

lambdas.append(lambda x = foo: x.value > 5) # bind x to foo from loop, check x.value

Full fix:

class TestObj():
    def __init__(self, value):
        self.value = value

lambdas = []
values_list = [10, 1]
for ele in values_list:
    foo = TestObj(ele)
    # use an x and bind it to this loops foo
    lambdas.append(lambda x = foo: x.value > 5)

# this is bad btw, use a simple for loop - do not use a list comp to create a list
# simply to print values 
print([single_lambda() for single_lambda in lambdas]) 

Output:

[True, False]

# and for the changed lambda with id() : the same id() twice

See Is it Pythonic to use list comprehensions for just side effects? regarding using list comprehension sideeffects and why its bad.


Related:

  • Unexpected behaviour with a conditional generator expression
like image 77
Patrick Artner Avatar answered Jan 19 '26 21:01

Patrick Artner



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!