8

I am trying to generate several functions with different parameter i (see below) using a for loop, but it seems that all these functions are using the last item of i's. Could anyone tell me how to handle this?

This is a simplified example. I actually need to generate more than 200 functions with different parameters.

funs = ()
for i in range(2):
    f = lambda x: x+i
    funs += (f,)

Then it turns out that the two functions do the same thing:

funs[0](1)

Output: 2

funs[1](1)

Output: 2

But I expect the first function to give a result of 1 rather than 2.

Thank you very much in advance.

2

2 Answers 2

6

The reason you're getting the same result for all the functions is because i is not local to the lambdas, but is defined in the outer scope, and it is accessed when the lambda is called - not when it is defined. At the end of the loop, the value of i is 1 and thus, it uses 1 for every call to the lambda functions.

Jean-Francois Fabre gave one good solution but I personally prefer this:

list_ = []
for i in range(2):
    f = lambda x, n=i: x+n
    list_.append(f)
Sign up to request clarification or add additional context in comments.

Comments

5

you have to break the dynamic binding to i, for instance by wrapping 2 lambdas together:

f = (lambda p : lambda x: x+p)(i)

that way, the value of i is captured, and functions hold a copy of i

Aside: I wouldn't use tuple to create the list for performance reasons when appending to funs (funs = () => funs = [])

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.