genexp surprise (wart?)

Mel Wilson mwilson-to at sympatico.ca
Fri May 26 14:29:16 CEST 2006


Paul Rubin wrote:
> "Paul Du Bois" <paul.dubois at gmail.com> writes:
>> The second is that you don't like the late-binding behavior of
>> generator expressions. PEP 289 has this to say:
>>
>>> After much discussion, it was decided that the first (outermost)
>>> for-expression should be evaluated immediately and that the remaining
>>> expressions be evaluated when the generator is executed.
> 
> Thanks.  That PEP is informative.  It shows that I stumbled into
> something that other people found confusing too, and that alternatives
> were considered that turned out not to be better.

The net effect of the bad version seems to be that you're
not getting a new generator from
     stream = (q for q in stream if q%p != 0)
(* disassembly shown below.)

Disassembly seems to show the program getting a pre-compiled
generator expression code block, and binding the new value
of p to it, then getting iter(stream), which is stream.  As
Paul Du Bois says, the outer loop is fixed, but the
subsequent if-expression is liable to change.

So 3 passes because 3%2 != 0
    4 passes because 4%3 != 0
    5 passes because 5%4 != 0
and so on.


         Interesting.

* Disassembly of stream = ...:

   6          47 LOAD_CLOSURE             0 (p)
              50 LOAD_CONST               2 (<code object 
<generator expression> at 009D65E0, file "try_eratos.py", 
line 6>)
              53 MAKE_CLOSURE             0
              56 LOAD_FAST                1 (stream)
              59 GET_ITER
              60 CALL_FUNCTION            1
              63 STORE_FAST               1 (stream)



More information about the Python-list mailing list