scoping with lambda in loops
Christos TZOTZIOY Georgiou
tzot at sil-tec.gr
Tue Sep 16 17:48:41 EDT 2003
On 16 Sep 2003 14:38:16 -0700, rumours say that imcmeans at telus.net (Ian
McMeans) might have written:
>First, I made multiple lambda functions inside a loop, each of which
>depended on the current loop variable.
>
>>>> a = []
>>>> for index in range(5):
> a.append(lambda: index)
>
>Now, see if you can guess what the output was for each of the
>functions in the list a:
>>>> a[0](), a[1](), a[2](), a[3](), a[4]()
>I had expected it to be (0, 1, 2, 3, 4), but actually, it's:
>
>(4, 4, 4, 4, 4)
>
>This really surprised me. I guess what is happening is that each
>lambda knows what the context of execution is where it was defined,
>and doesn't actually evaluate until the function is called, and when
>it does evaluate, it uses the current value of the variable. Is this
>related to static scoping? A similar thing would happen if you defined
>a nested function that used a variable declared in the outer function,
>then changed that variable, and called the nested function.
>
>Can someone recommend a way to code around this gotcha? I'm having
>trouble. I want the functions created inside the loop to execute with
>the value of the loop index at the moment when the function is made.
I think this is a FAQ (perhaps it was FAQ 6.10?), and you can find many
threads on the subject if you do a search on groups.google.com.
The typical way to deal with this, IIRC, is to change your lambda
declaration into:
> a.append(lambda index=index: index)
so that index gets evaluated at definition time.
--
TZOTZIOY, I speak England very best,
Microsoft Security Alert: the Matrix began as open source.
More information about the Python-list
mailing list