[Python-ideas] if-statement in for-loop

Paul Moore p.f.moore at gmail.com
Tue Oct 4 04:39:58 EDT 2016


On 4 October 2016 at 08:56, Stephen J. Turnbull
<turnbull.stephen.fw at u.tsukuba.ac.jp> wrote:
> These are my opinions; I don't claim any authority for them.  I just
> don't find the proposed syntax as obvious and unambiguous as you do,
> and would like to explain why that is so.
>
> Ken Kundert writes:
>
>  > In my experience it is exceptions and inconsistencies that consume 'working
>  > memory in the brain of humans'. By eliminating the distinction between list
>  > comprehensions and for loops we would be making the language simpler by
>  > eliminating an inconsistency.
>
> I don't think of a comprehension as a for loop, I think of it as
> setbuilder notation (although of course I realize that since lists are
> sequences it has to be a for loop under the hood).  So the claimed
> inconsistency here doesn't bother me.  I realize it bothers a lot of
> people, but the proposed syntax is not obvious to me (ambiguous and
> inconsistent in its own way).
>
>  > [T]he writing of the generator function represents a speed bump.
>
> It used to be, for me, but it really isn't any more.  Perhaps you
> might get used to it if you tried it.  Harder to argue: the fact that
> Guido and Nick (inter alia) consider it good style to use named
> functions makes that point a hard sell (ie, you don't need to convince
> me, you need to convince them).
>
>  > Whereas writing something like the following is simple, compact,
>  > quick, and obvious. There is no reason why it should not be allowed
>  > even though it might not always be the best approach to use:
>  >
>  >     for i in range(5) for j in range(5) for k in range(5):
>  >         ...
>
> To me, that is visually ambiguous with
>
> for i in (range(5) for j in (range(5) for k in range(5))):
>     ...
>
> although syntactically the genexp requires the parentheses (and in
> fact is almost nonsensical!)  I could easily see myself forgetting the
> parentheses (something I do frequently) when I *do* want to use a
> genexp (something I do frequently), with more or less hilarious
> results.  As already mentioned:
>
> for i, j, k in itertools.product(range(5), range(5), range(5)):
>     ...
>
> To me that is much clearer, because it expresses the rectangular shape
> of the i, j, k space.  I would also stumble on
>
> for i in range(5) for j in range(i + 1):
>     ...
>
> at least the first few times I saw it.  Based on the English syntax of
> "for" (not to mention the genexp syntax), I would expect
>
> for j in range(i + 1) for i in range(5):
>     ...
>
> If itertools.product is the wrong tool, then the loop bodies are
> presumably complex enough to deserve new indent levels.  Note that
> simple filters like non_nil (see below) can easily be used, as long as
> the resulting set is still a product.
>
>  > And I would really like to be able to write loops of the form:
>  >
>  >     for item in items if item is not None:
>  >        ...
>
> def non_nil(items):
>     return (item for item in items if item is not None)
>
> for item in non_nil(items):
>     ...
>
> I think that's very readable, so the only reason why that 2-line
> function needs to be syntax that I can see is your distaste for
> defining functions, and that of other Python programmers who think
> like you.

Again this is just personal opinion, but I agree 100% with everything
Stephen said.

It *is* a stumbling block to get used to writing generator functions
like non_nil() above, but it's also a worthwhile learning experience.
And yes, it's somewhat inconvenient to do so if you're working in the
standard Python REPL, but designing language features around REPL
usage isn't (IMO) the right choice. And if you really need a better
way of handling that sort of refactoring in an interactive
environment, tools like the Jupyter notebook are probably what you're
looking for.

(Trying to collapse multiple clauses into one line/statement is
something Perl was famous for, and it's in many ways quite an
attractive feature. But IMO it directly contributes to Perl's
reputation for unreadability, because it *does* get used too much,
whether you think it will or not - one person's "nicely compact" is
another person's "obfuscated". So I'm glad that Python's design avoids
encouraging that style - even though I do occasionally remember fondly
my Perl one-liners :-))

Paul


More information about the Python-ideas mailing list