semicolon at end of python's statements

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri Aug 30 20:09:26 EDT 2013


On Fri, 30 Aug 2013 11:32:17 +0100, Fábio Santos wrote:

> On 29 Aug 2013 23:20, "Ben Finney" <ben+python at benfinney.id.au> wrote:
>>
>> Fábio Santos <fabiosantosart at gmail.com> writes:
>>
>> > It is a shame that this is not possible in python. for..if exists in
>> > comprehensions and not in regular loops but that would be nice
>> > sometimes.
>>
>> So you use it in a generator expression, and iterate over the
>> generator:
>>
>>     for foo in (spam for spam in sequence if predicate(spam)):
>>         process(spam)
>>
>> That way, there's no need for new syntax.
> 
> The problem I have with that strategy is that it is repetitive and
> hinders readability. You wrote "for" and "in" twice, and spam (a pretty
> useless intermediate variable) thrice! 

There is no need for spam to be "intermediate", and the fact that it 
shouldn't be is demonstrated by Ben's error in referring to "process
(spam)" instead of "process(foo)".

We really are spoiled for choice here. We can write any of these:

# Option 1
for spam in sequence:
    if predicate(spam):
        process(spam)

# Option 2
for spam in filter(predicate, sequence):
    process(spam)

# Option 3
for spam in (spam for spam in sequence if predicate(spam)):
    process(spam)


Adding a fourth option:

for spam in sequence if predicate(spam):
    process(spam)

saves absolutely nothing except a line and an indent level, neither of 
which are in short supply, and gains nothing in readability over Option 1.



> While it does its job, it hides
> the true intent for filtering beneath a lot of (pun intended) spam. The
> "if" particle is nigh undetectable there.
> 
> To get around this, I often declare a generator. But I still find it a
> bit awkward to have to look up the definition elsewhere, and to waste
> lines over something so simple.

No need to look up a definition elsewhere, you can put the generator 
right next to the loop:

gen = (spam for spam in sequence if predicate(spam))
for spam in gen:
    process(spam)


But of all the options shown, including the hypothetical for...if, I 
still prefer Option 1, or Option 2 as my second option.



-- 
Steven



More information about the Python-list mailing list