[Python-Dev] Don't set local variable in a list comprehension or generator

Amaury Forgeot d'Arc amauryfa at gmail.com
Wed May 18 23:37:30 CEST 2011


Hi,

2011/5/18 Terry Reedy <tjreedy at udel.edu>:
> On 5/18/2011 10:19 AM, Nadeem Vawda wrote:
>
>> I'm not sure why you would encounter code like that in the first place.
>> Surely any code of the form:
>>
>>     ''.join(c for c in my_string)
>>
>> would just return my_string? Or am I missing something?
>
> Good question. Anything useful like "'-'.join(c for c in 'abc')" is the same
> as "'-'.join('abc'). The same, as far as I can think of, for anything like
> list() or set() taking an iterable arg.

With a little imagination you can build something non trivial.
For example, a join_words function:

def join_words(words):
    return ', '.join(w.strip() for w in words)

Like Victor says, the code of the generator object contains a
STORE_FAST followed by LOAD_FAST.
This pair of opcodes could be removed, and the value left on the stack.

>>> dis.dis(join_words.func_code.co_consts[2])
  1           0 SETUP_LOOP              24 (to 27)
              3 LOAD_FAST                0 (.0)
        >>    6 FOR_ITER                17 (to 26)
              9 STORE_FAST               1 (w)
             12 LOAD_FAST                1 (w)
             15 LOAD_ATTR                0 (strip)
             18 CALL_FUNCTION            0
             21 YIELD_VALUE
             22 POP_TOP
             23 JUMP_ABSOLUTE            6
        >>   26 POP_BLOCK
        >>   27 LOAD_CONST               0 (None)
             30 RETURN_VALUE

It's probably not easy to do though.
Think of expressions where the variable appears several times,
or even where the variable is not the first object, like str(ord(x)).

-- 
Amaury Forgeot d'Arc


More information about the Python-Dev mailing list