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

Terry Reedy tjreedy at udel.edu
Thu May 19 03:59:47 CEST 2011


On 5/18/2011 5:37 PM, Amaury Forgeot d'Arc wrote:

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 mystring) would just return mystring? 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 joinwords function: def joinwords(words): return ', '.join(w.strip() for w in words) Like Victor says, the code of the generator object contains a STOREFAST followed by LOADFAST. This pair of opcodes could be removed, and the value left on the stack. dis.dis(joinwords.funccode.coconsts[2]) 1 0 SETUPLOOP 24 (to 27) 3 LOADFAST 0 (.0) >> 6 FORITER 17 (to 26) 9 STOREFAST 1 (w) 12 LOADFAST 1 (w) 15 LOADATTR 0 (strip) 18 CALLFUNCTION 0 21 YIELDVALUE 22 POPTOP 23 JUMPABSOLUTE 6 >> 26 POPBLOCK >> 27 LOADCONST 0 (None) 30 RETURNVALUE

As I pointed out in response to Victor, you get nearly the same with bytecode with regular old for loops; in particular, the store x/load x pair.

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)).

Where first means first in left-to-right order rather than in innermost to outermost order. (OT: I think Python is a bit unusual in this way.)

-- Terry Jan Reedy



More information about the Python-Dev mailing list