"For" loop and list comprehension similarity

S

s.lipnevich

Hi All,

I apologize if this was brought up before, I couldn't find any "prior
art" :).
On more than one occasion, I found myself wanting to use a "conditional
loop" like this (with "Invalid syntax" error, of course):

for i in c if <test>:
print i*2

....because it's similar to the list comprehension construct:

[i*2 for i in c if <test>]
---------

Is this the intended difference in constructs? The available equivalent
feels a bit awkward:

for i in c:
if <test>:
print i*2

Just curious. Thanks!

Sergey.
 
M

Mitja Trampus

On more than one occasion, I found myself wanting to use a "conditional
loop" like this (with "Invalid syntax" error, of course):

for i in c if <test>:
print i*2

Maybe there's been a PEP, don't really know...
Currently, the only sensible alternative is what you've written below:
The available equivalent
feels a bit awkward:

for i in c:
if <test>:
print i*2


This indeed doesn't look nice, especially if you've got lots of code instead of just
print. An alternative which avoids double indentation is

for i in c:
if not <test>: continue
print i*2
 
S

s.lipnevich

Thank you for replying, Mitja! That *is* a nice alternative.

Do you think it's a good idea to ask on comp.python.devel if they would
be interested in a PEP about this (provided there is none)?

Cheers,
Sergey.
 
G

Grant Edwards

Hi All,

I apologize if this was brought up before, I couldn't find any "prior
art" :).
On more than one occasion, I found myself wanting to use a "conditional
loop" like this (with "Invalid syntax" error, of course):

for i in c if <test>:
print i*2

...because it's similar to the list comprehension construct:

[i*2 for i in c if <test>]
---------

Is this the intended difference in constructs? The available equivalent
feels a bit awkward:

for i in c:
if <test>:
print i*2

for j in [i*2 for i in c if <test>]:
print j
 
B

Ben Finney

On more than one occasion, I found myself wanting to use a "conditional
loop" like this (with "Invalid syntax" error, of course):

for i in c if <test>:
print i*2

...because it's similar to the list comprehension construct:

[i*2 for i in c if <test>]

Why not combine the two:

for i in [j for j in c if <test>]:
print i*2
 
S

s.lipnevich

Why not combine the two:

I guess because (at least in source code) you're doing a loop twice
:). I don't know what a compiler would do. I think though that the
"for i in c if test:" construct is more readable and maybe can even be
better optimized.
Thanks!

Sergey.
 
J

John Zenger

Rather than a list comprehension, it would be faster and more
memory-efficient to use a generator comprehension. Just change the
square brackets to parentheses:

for j in (i*2 for i in c if <test>):
print j


Grant said:
Hi All,

I apologize if this was brought up before, I couldn't find any "prior
art" :).
On more than one occasion, I found myself wanting to use a "conditional
loop" like this (with "Invalid syntax" error, of course):

for i in c if <test>:
print i*2

...because it's similar to the list comprehension construct:

[i*2 for i in c if <test>]
---------

Is this the intended difference in constructs? The available equivalent
feels a bit awkward:

for i in c:
if <test>:
print i*2


for j in [i*2 for i in c if <test>]:
print j
 
T

Terry Reedy

I guess because (at least in source code) you're doing a loop twice
:). I don't know what a compiler would do. I think though that the
"for i in c if test:" construct is more readable and maybe can even be
better optimized.

There are also the filter and ifilter functions:

for i in filter(testfunc, c):

tjr
 
S

s.lipnevich

I think I like generator comprehension in this case better than either
list comprehension or a filter because both of the latter create a new
full "result list" before the loop even begins. At least I suppose they
do. Also, I think Mitja's suggestion "if not <test>: continue" and
Terry's filter function are more readable than comprehensions.
It's not a contest though :), all these variants are great, thank you
all!
Do you think this discussion is a proof that the following principle
got violated, or do you think that "loop with condition" is not such an
atomic thing to be subject to this: "There should be one -- and
preferably only one -- obvious way to do it."
Cheers,

Sergey.
 
P

Peter Hansen

Do you think this discussion is a proof that the following principle
got violated, or do you think that "loop with condition" is not such an
atomic thing to be subject to this: "There should be one -- and
preferably only one -- obvious way to do it."

Mitja's suggestion was the one obvious way. The others are all
interesting, maybe even preferable in some cases, but I don't think most
experienced Python programmers would be more likely to start with one of
them than with the simple for-loop-with-explicit-test.

-Peter
 
T

Terry Reedy

Peter Hansen said:
Mitja's suggestion was the one obvious way. The others are all
interesting, maybe even preferable in some cases, but I don't think most
experienced Python programmers would be more likely to start with one of
them than with the simple for-loop-with-explicit-test.

If by 'explicit-test' you mean a nested if-statement, then I agree. When I
mentioned filter() as one way to avoid the obvious, I was aware that it
creates an intermediate list that is usually not needed. (And if it is
needed, then it should be name-assigned before the loop.)

Terry Jan Reedy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top