
On Tuesday 21 October 2003 06:53 pm, Guido van Rossum wrote: ...
maybe an optimization IS possible if all the user code does with the LC is loop on it (or anyway just get its iter(...) and nothing else).
But that's not very common, so I don't see the point of putting in the
It IS common, at least in the code I write, e.g.:
d = dict([ (f(a), g(a)) for a in S ])
s = sets.Set([ a*a for a in S ])
totsq = sum([ x*x for x in S ])
etc. I detest the look of those ([ ... ]), but that's the closest I get to dict comprehensions, set comprehensions, etc.
OK, but you hve very little hope of optimizing the incarnation away by the compiler (especially since our attempts at warning about surreptitious changes to builtins had to be withdrawn before 2.3 went out).
except when it doesn't, and then making the list comprehension lazy can be a mistake: the following example
for key in [k for k in d if d[k] is None]: del d[key]
is *not* the same as
for key in d: if d[key] is None: del d
Well, no, but even if that last statement was "del d[key]" you'd still be right:-).
:-(
Even in a situation where the list comp is only looped over once, code MIGHT still be relying on the LC having "snapshotted" and/or exhausted iterators IT uses. I was basically thinking of passing the LC as argument to something -- the typical cases where I use LC now and WISH they were lazy, as above -- rather about for loops. And even when the LC _is_ an argument there might be cases where its current strict (nonlazy) semantics are necessary. Oh well!
Yes, this is why iterator comprehensions (we need a better term!!!) would be so cool to have (I think much cooler than conditional expressions). --Guido van Rossum (home page: http://www.python.org/~guido/)