3

As part of another experience i encountered a problem in the list comprehension. In order to put simply, if I am trying the following code:

m = [ k**2 for k in range(7)]
print m
[0, 1, 4, 9, 16, 25, 36]
print k
6
  1. My question is how is it python is able to get the value of k, outside the list comprehension?
  2. Why is k not garbage collected?
  3. Is this not a memory leak?
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Blueice
  • 143
  • 9

2 Answers2

11

Because in Python 2, the list variable 'leaks' to the surrounding scope. This was a mistake in the way list comprehensions were built.

This has been corrected for dict and set comprehensions, generator expressions and in Python 3 for list comprehensions as well.

It is not a memory leak. It's just an error in the scope of the variable.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • This isn't actually a mistake. The idea was that it should behave the same as the equivalent `for` loop. `for` loops don't have their own scope, so neither do list comprehensions. They changed their mind later. – kindall May 17 '13 at 16:25
  • 4
    The conclusion was that the decision to have them behave like `for` loops was the mistake :-) It turned out to be confusing people, and the behaviour was altered. – Martijn Pieters May 17 '13 at 16:28
7

No, it's not a memory leak as that term is usually defined. In Python 2.x, a list comprehension is not a separate scope, so a variable you use in a list comprehension is in the scope of the function that contains it. You can easily see this in action by setting k before the list comprehension; the listcomp will clobber it.

Because a valid reference exists, the object k points to is (properly) not garbage collected.

In Python 3.x, this was changed; all comprehensions create their own scopes and do not "leak" into the enclosing scope.

In Python 2.x, generator expressions do have their own scope, however, so if you want that behavior, just write it like this:

m = list(k**2 for k in range(7))
kindall
  • 178,883
  • 35
  • 278
  • 309
  • The problem is that if you have earlier declared the variable k & want to use it after list comprehension, the value of k gets changed. – Blueice May 23 '13 at 15:17