Hello, This is an idea about something I'd like to see
implemented in python.  I understand that's the purpose of
PEPs, so I'll write it as a PEP, but send it here to receive
your valuable feedback.

Abstract

This is a proposal to increase the richness of for loops,
only to the extent that it equals that of list and generator
comprehensions. In the opinion of the proponent, this will
make the language more uniform and would reduce the excessive
level of nesting that is required sometimes, without
introducing special keywords, or breaking backwards
compatibility.

The PEP suffers from several problems. Some of them related to being quite unclear in several edges, others are real problems.

This PEP is independent of, but related to PEP 3142.

Rationale
The syntax of a for loop is restricted to the following:
   for element in list:
       instructions

Nesting for loops and conditionals is possible, of course:
for x in list1:
    for y in list2:
        if condition(x,y):
            func2(x,y)

However, for list and generator comprehensions, the syntax is
more concise:
list=[func(x,y,..) for x in list1 for y in list2
...        if condition(x,y,...)]

Loops and comprehensions serve for similar purposes, and
sometimes what was first written in one way is finally
changed into the other. Thus it would be convenient to allow
for more similar syntax in both of them.  This requires that
the syntax of a for loop allows for nested for and
conditionals (and possibly while loops (see PEP 3142))

for x in list1 for y in list2 ... if condition(x,y,...):
    ''instructions''

In general, whenever
[expression1  iterator]
is a valid list comprehension, then
iterator:
    statements
should be a valid loop.

As another example, it is sometimes the case that an
iteration over two lists can be rewritten as a single
iteration:
for x in range(10) for y in range(10) if x+y==5:
    print x,y

What is that supposed to mean? Nested looping? Why is that (confusing thing) better than:

from itertools import product

for x, y in product(range(10), range(10)) if x + y == 5:
    print x, y

is equivalent to
for x in range(6):
    print x,5-y

How is that equivalent? The second one is generated using completely different logic than the second one (not to mention it is shorter, simpler, and faster).

it is somewhat more conceptual to think of the first
iteration as a single loop.

It is actually possible to come very close to the notation
proposed using the generator comprehensions introduced in
python 2.5:
for x,y in ((x,y) for x in range(10) for y in range(10) if x+y==5):
    print x,y
but this notation is cumbersome.

This PEP responds to the philosophy that if a nesting level
is unused, it should be avoided. For example, in the code:

If a nesting level is unused... shouldn't just the whole thing be deleted? I'm unclear on what you mean by "unused nesting level"

for x in list1:
    func1(x)
    for y in list2:
       if cond(x,y):
          func(x,y)
    func3(x)

the second nesting  level doesn't contain any statements and
thus, should this PEP be passed, it should be written:

What do you mean by "doesn't contain any statements"? If statement is not a statement?

for x in list1:
    func1(x)
    for y in list2 if cond(x,y):
          func(x,y)
    func3(x)


+1 on the "if" and (possibly) "while" conditional looping.
-1 on shorthand nested for.
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to