In Python 2.x the loop variable is part of the containing scope:
>>> a
Traceback (most recent call last):
File "", line 1, in
NameError: name 'a' is not defined
>>> [a*2 for a in (1,2,3)]
[2, 4, 6]
>>> a
3
In Python 3.x, it is not:
>>> a
Traceback (most recent call last):
File "", line 1, in
NameError: name 'a' is not defined
>>> [a*2 for a in (1,2,3)]
[2, 4, 6]
>>> a
Traceback (most recent call last):
File "", line 1, in
NameError: name 'a' is not defined
It is sometimes useful to know why something failed. The following Python 2 code will not work in Python 3:
>>> import math
>>> try:
... values = [math.sqrt(x) for x in (1, 2, -3, 4)]
... except ValueError:
... print("cannot compute sqrt(%r)" % x)
...
cannot compute sqrt(-3)
I have mostly found this feature of Python 2 to be useful on the interactive shell, when trying to diagnose what caused an error in my list comprehension. Eg.
>>> with open("tmp.dat") as input_file:
... fields = [line.split()[3] for line in input_file]
...
Traceback (most recent call last):
File "", line 2, in
IndexError: list index out of range
>>> line
'one two three\n'
Oops, there are only 3 columns, not 4.