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

Stephen J. Turnbull turnbull.stephen.fw at u.tsukuba.ac.jp
Tue Oct 4 03:56:12 EDT 2016


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.



More information about the Python-ideas mailing list