0

I understand that:

a=[lambda :k for k in [1,2,3]]
[e() for e in a]

returns [3, 3, 3] because it takes the value of k at runtime, and the last value of k is 3. However, I don't understand why, if I do:

k=50
[e() for e in a]

I still get [3, 3, 3]. Why this? I updated the value of k with 50, why do(es) the e() function(s) still read the old k value?

asked Jan 10, 2021 at 22:20
3
  • 3
    The ‘k’ in the list comprehension has a different scope. Commented Jan 10, 2021 at 22:25
  • so is it no more accessible from outside the list comprehension? Commented Jan 10, 2021 at 22:28
  • Try print(k) after creating the list comprehension. Commented Jan 10, 2021 at 22:29

1 Answer 1

1

Although you just said it is clear, that

a=[lambda :k for k in [1,2,3]]
[e() for e in a]

returns [3,3,3], this needs a few words. And for sure this is not clear for everybody. The first list comprehensions creates three functions. They all take no arguments and they all return the variable k. Inside the list comprehension k is not a number. K is a variable. And your three functions return that variable. So you have three identical functions. Normally the k variable would be lost. It scopes only withing the list comprehension. You cannot access it any more outside the list comprehension. But in your special case k still lives. It is still captured in the three functions, because these return it. This is what is called a closure (of k). And as k was for iterating through the list [1,2,3] at the end it still is 3. So all three functions return 3. But that is not so obvious. Python could also set it back to zero again or a random number. There is no such statement that k remains at the last value. So even if your code returns [3, 3, 3], that is not obvious and that is not guaranteed.

As said k is not accessible any more outside the list comprehension. It is in the scope of the list comprehension only. Only with the three a-functions you have ever access to that k. And on the other hand, you cannot tell the a-funcions to use another k. The k from the list comprehension is in their closure. The k=50 has a completely different scope.

If you want the other k in the a-functions, you must define them this way:

a=[lambda k : k_compr for k_kompr in [1,2,3]]
[e() for e in a]

and pass the k to them. But I think you question is just informatory. Nobody would ever use such a list comrehension.

answered Jul 10, 2022 at 19:43
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.