[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