[Python-ideas] Accessing the result of comprehension's expression from the conditional

Paul Moore p.f.moore at gmail.com
Fri Jun 19 10:15:53 CEST 2009

2009/6/19 Lie Ryan <lie.1296 at gmail.com>:
> res = [x**x as F for x in nums if F < 100]
> (note: this is my new preferred syntax)
> Advantages of the proposal:
> - shorter
> - faster, as looping is done in C
> - more readable. The main advantage of comprehension is that it have
> standardized form, which is easier to understand, unlike a for-loop
> which can have an infinite number of variations.
> - (unnecessary) nested comprehension is an abuse.
> - with `as` keyword, no new keyword and no ambiguity since currently
> `as` cannot exist inside comprehension.
> Disadvantages:
> - reverses the current semantic of filtering-then-expression. This
> shouldn't be too much problem since side-effect on the expression part
> is a cardinal sin and...
> - if the expression part is heavy, it might be possible to do
> optimization by filtering first when the filter part does not require
> the result (i.e. when there is no "as" clause). A good side effect of
> this optimization is codes that relies on filtering being done before
> expression will just work as they cannot contain an `as` keyword.
> (As "simple is better than complex", I actually don't really like `as`
> can change evaluation order; I much prefer to keep everything simple and
> consistent, i.e. always evaluate expression then filter or otherwise)
> possible syntaxes:
> - [x**x as F for x in nums if F < 100]
>  the as keyword is already often used to rename things
>  (in with, import, etc) I like this one much better than @. The as
>  part, of course, is optional
> - [x**x for x in nums if @ < 100]
>  the initial proposed syntax, ugly as hell.

OK, with this explanation (and the new syntax) I see what you're
getting at better.

However, changing the order of evaluate vs filter is a huge
compatibility problem. There's no way this will be possible. Even with
syntax triggering the change (so that it's one way with the "as", the
other without), that's a disaster waiting to happen.

You have at least 3 explicit ways of stating your intent (genexp
inside listcomp, map inside listcomp, explicit loop). None is as
clean-looking as your (amended) proposal, but they work now, and they
don't have the semantic issues of your proposal.

(For a more general, more radical, equally certain to be shot down,
option, which at least doesn't introduce the change in semantics, you
could try proposing "as" as an assignment-as-expression operator. So
you could have

    [y for x in l if (f(x) as y) < 100]

Hmm, on second thoughts - no, don't bother... :-))


More information about the Python-ideas mailing list