On Fri, 13 Jul 2012 21:53:10 -0700, rusi wrote: > On Jul 14, 8:43 am, Steven D'Aprano <steve > +comp.lang.pyt...@pearwood.info> wrote: >> On Fri, 13 Jul 2012 19:31:24 -0700, rusi wrote: >> > Consider the following >> >> > def foo(x): >> > i = 100 >> > if x: >> > j = [i for i in range(10)] >> > return i >> > else: >> > return i >> >> A simpler example: >> >> def foo(): >> i = 100 >> j = [i for i in range(10)] >> return i >> >> In Python 3, foo() returns 100; in Python 2, it returns 9. > > You did not get the point.
I got the point. I just thought it was unnecessarily complex and that it doesn't demonstrate what you think it does. > Converting my example to your format: > > def foo_steven(n): > i = 100 > j = [i for i in range(n)] > return i > > $ python3 > Python 3.2.3 (default, Jun 26 2012, 00:38:09) [GCC 4.7.1] on linux2 > Type "help", "copyright", "credits" or "license" for more information. >>>> def foo_steven(n): > ... i = 100 > ... j = [i for i in range(n)] > ... return i > ... >>>> foo_steven(0) > 100 >>>> foo_steven(4) > 100 Yes, we know that in Python 3, list comprehensions create their own scope, and the loop variable does not leak. > $ python > Python 2.7.3rc2 (default, Apr 22 2012, 22:35:38) [GCC 4.6.3] on linux2 > Type "help", "copyright", "credits" or "license" for more information. >>>> def foo_steven(n): > ... i = 100 > ... j = [i for i in range(n)] > ... return i > ... >>>> foo_steven(0) > 100 >>>> foo_steven(3) > 2 Yes, we know that in Python 2, list comprehensions don't create their own scope, and consequently the list variable does leak. > Python 2: > When n>0 comprehension scope i is returned > When n=0 function scope i is returned Incorrect. In Python 2, *there is no comprehension scope*. There is only local scope. In Python 2, regardless of the value of n, the local variable i is ALWAYS returned. It just happens that sometimes the local variable i is modified by the list comprehension, and sometimes it isn't. In Python 2, this is no more mysterious than this piece of code: def example(n): i = 100 for i in range(n): pass return i py> example(0) 100 py> example(4) 3 If the loop doesn't execute, the loop variable isn't modified. In Python 2, it doesn't matter whether you use a for-loop or a list comprehension, the loop variable is local to the function. > Python 3: The return statement is lexically outside the comprehension > and so that outside-scope's i is returned in all cases. Correct. In Python 3, list comprehensions now match generator expressions and introduce their own scope which does not effect the local function scope. Some history: http://bugs.python.org/issue510384 http://bugs.python.org/issue1110705 -- Steven -- http://mail.python.org/mailman/listinfo/python-list