removing list comprehensions in Python 3.0

Bengt Richter bokr at oz.net
Sun Jul 10 09:01:07 CEST 2005


On Sat, 09 Jul 2005 22:32:22 -0600, Steven Bethard <steven.bethard at gmail.com> wrote:

>Raymond Hettinger wrote:
>> [Steven Bethard]
>> 
>>>I would hope that in Python 3.0 list comprehensions and generator
>>>expressions would be able to share a large amount of implementation, and
>>>thus that the speed differences would be much smaller.  But maybe not...
>> 
>> Looking under the hood, you would see that the implementations are
>> necessarily as different as night and day.  Only the API is similar.
>
>Necessarily?  It seems like list comprehensions *could* be implemented 
>as a generator expression passed to the list constructor.  They're not 
>now, and at the moment, changing them to work this way seems like a bad 
>idea because list comprehensions would take a performance hit.  But I 
>don't understand why the implementations are *necessarily* different. 
>Could you explain?
>
>STeVe
>
>P.S. The dis.dis output for list comprehensions makes what they're doing 
>pretty clear.  But dis.dis doesn't seem to give me as much information 
>when looking at a generator expression:
>
>py> def ge(items):
>...     return (item for item in items if item)
>...
>py> dis.dis(ge)
>   2           0 LOAD_CONST               1 (<code object <generator 
>expression> at 0116FD20, file "<interactive input>", line 2>)
>               3 MAKE_FUNCTION            0
>               6 LOAD_FAST                0 (items)
>               9 GET_ITER
>              10 CALL_FUNCTION            1
>              13 RETURN_VALUE
>
>I tried to grep through the dist\src directories for what a generator 
>expression code object looks like, but without any luck.  Any chance you 
>could point me in the right direction?

 >>> import dis
 >>> g = ge([1,2,0,3,'',4])
 >>> dis.dis(g)
 Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File "d:\python-2.4b1\lib\dis.py", line 46, in dis
     raise TypeError, \
 TypeError: don't know how to disassemble generator objects

but:

 >>> dis.dis(ge)
   2           0 LOAD_CONST               1 (<code object <generator expression> at 02EE4FA0, file "<stdin>", line 2>)
               3 MAKE_FUNCTION            0
               6 LOAD_FAST                0 (items)
               9 GET_ITER
              10 CALL_FUNCTION            1
              13 RETURN_VALUE
 >>> ge.func_code
 <code object ge at 02EE4E60, file "<stdin>", line 1>
 >>> ge.func_code.co_consts
 (None, <code object <generator expression> at 02EE4FA0, file "<stdin>", line 2>)
 >>> ge.func_code.co_consts[1]
 <code object <generator expression> at 02EE4FA0, file "<stdin>", line 2>
 >>> dis.dis(ge.func_code.co_consts[1])
   2           0 SETUP_LOOP              28 (to 31)
               3 LOAD_FAST                0 ([outmost-iterable])
         >>    6 FOR_ITER                21 (to 30)
               9 STORE_FAST               1 (item)
              12 LOAD_FAST                1 (item)
              15 JUMP_IF_FALSE            8 (to 26)
              18 POP_TOP
              19 LOAD_FAST                1 (item)
              22 YIELD_VALUE
              23 JUMP_ABSOLUTE            6
         >>   26 POP_TOP
              27 JUMP_ABSOLUTE            6
         >>   30 POP_BLOCK
         >>   31 LOAD_CONST               0 (None)
              34 RETURN_VALUE

A little more info, anyway. HTH.

Regards,
Bengt Richter



More information about the Python-list mailing list