Try running this code in a fresh interpreter:
>>> cells = [[1, 2, 3], [4, 5, 6]]
>>> [cell for cell in row for row in cells]
NameError: name 'row' is not defined
It works in your code because something's defined a row
variable. But what?
in python 2.x, list comprehensions leak local variables (generator, set, and dictionary comprehensions, or 3's list comprehensions, do not)
In the following:
>>> [cell for row in cells for cell in row]
[1, 2, 3, 4, 5, 6]
>>> row
[4, 5, 6]
>>> cell
6
cell
and row
are added to the local scope. When you run the next test case, you're unintentionally using this old value of row
:
>>> [cell for cell in row for row in cells ]
[4, 4, 5, 5, 6, 6]
This is only true of list comprehensions in python 2.x.
One way to avoid being caught out by this is to use list(... for x in ...)
instead of [... for x in ...]
.