List comprehension/genexp inconsistency.

Steve Howell showell30 at yahoo.com
Wed Mar 21 04:07:52 CET 2012


On Mar 20, 3:50 pm, Ian Kelly <ian.g.ke... at gmail.com> wrote:
> On Tue, Mar 20, 2012 at 3:16 PM, Dennis Lee Bieber
>
> <wlfr... at ix.netcom.com> wrote:
> > On Tue, 20 Mar 2012 16:23:22 -0400, "J. Cliff Dyer"
> > <j... at sdf.lonestar.org> declaimed the following in
> > gmane.comp.python.general:
>
> >> When trying to create a class with a dual-loop generator expression in a
> >> class definition, there is a strange scoping issue where the inner
> >> variable is not found, (but the outer loop variable is found), while a
> >> list comprehension has no problem finding both variables.
>
> >        Readhttp://www.python.org/dev/peps/pep-0289/-- in particular, look
> > for the word "leak"
>
> No, this has nothing to do with the loop variable leaking.  It appears
> to have to do with the fact that the variables and the generator
> expression are inside a class block.

Interesting.

Just for completeness, the code does seem to work fine when you take
it out of the class:

  Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49)
  [GCC 4.2.1 (Apple Inc. build 5646)] on darwin
  Type "help", "copyright", "credits" or "license" for more
information.
  >>> foo, bar = 4, 4
  >>> g = (((x, y), x+y) for x in range(foo) for y in range(bar))
  >>> dict(g)
  {(0, 1): 1, (1, 2): 3, (3, 2): 5, (0, 0): 0, (3, 3): 6, (3, 0): 3,
(3, 1): 4, (2, 1): 3, (0, 2): 2, (2, 0): 2, (1, 3): 4, (2, 3): 5, (2,
2): 4, (1, 0): 1, (0, 3): 3, (1, 1): 2}
  >>> import dis
  >>> dis.dis(g.gi_code)
    1           0 SETUP_LOOP              57 (to 60)
                3 LOAD_FAST                0 (.0)
          >>    6 FOR_ITER                50 (to 59)
                9 STORE_FAST               1 (x)
               12 SETUP_LOOP              41 (to 56)
               15 LOAD_GLOBAL              0 (range)
               18 LOAD_GLOBAL              1 (bar)
               21 CALL_FUNCTION            1
               24 GET_ITER
          >>   25 FOR_ITER                27 (to 55)
               28 STORE_FAST               2 (y)
               31 LOAD_FAST                1 (x)
               34 LOAD_FAST                2 (y)
               37 BUILD_TUPLE              2
               40 LOAD_FAST                1 (x)
               43 LOAD_FAST                2 (y)
               46 BINARY_ADD
               47 BUILD_TUPLE              2
               50 YIELD_VALUE
               51 POP_TOP
               52 JUMP_ABSOLUTE           25
          >>   55 POP_BLOCK
          >>   56 JUMP_ABSOLUTE            6
          >>   59 POP_BLOCK
          >>   60 LOAD_CONST               0 (None)
               63 RETURN_VALUE



More information about the Python-list mailing list