New to Python - block grouping (spaces)

Chris Angelico rosuav at gmail.com
Thu Apr 16 15:41:22 CEST 2015


On Thu, Apr 16, 2015 at 9:07 PM, Antoon Pardon
<antoon.pardon at rece.vub.ac.be> wrote:
> On 04/16/2015 12:43 PM, Steven D'Aprano wrote:
>> On Thursday 16 April 2015 20:09, Antoon Pardon wrote:
>>
>>> I beg to differ. The most common occurence is a loop with a break
>>> condition in the middle I would prefer such a loop to be written as
>>> follows:
>>>
>>> repeat:
>>>     some
>>>     code
>>> break_when condition:
>>>     more
>>>     code

The case of a loop structure with its condition in the middle is one
that few languages support, so the physical structure has to be
something like:

goto middle
while not condition:
    more code
    label middle
    some code

or

while True:
    some code
    if condition: break
    more code

or maybe

some code
while not condition:
    more code
    some code

But I'm not sure how you could represent this more appropriately,
regardless of your indentation. Unindenting an "if" in the middle of a
loop doesn't instantly scream "this is the loop header". Using a goto
to jump half way into a loop is a really REALLY bad idea in most
programs (and it's illegal in lots of languages anyway). Repeating the
setup code is fine if it's a single line, but not else.

Similar to this is the capturing condition. Say you want to process
lines until you get to one that consists solely of a full stop. In C,
you can do this (kinda); in Pike, where strings are first-class
objects (like Python, unlike C), you can definitely do it,
syntactically:

while ((line=get_next_line()) != ".")
    process_line(line);

Perfectly legal. Not perfectly readable. In Python, your options are a
helper generator function:

def next_line():
    while True:
        line = get_next_line()
        if line==".": break
        yield line
for line in next_line():
    process_line(line)

or a loop with a critical line of code duplicated above and at the
bottom of the loop (risks 'continue' failure):

line = get_next_line()
while line!=".":
    process_line(line)
    line = get_next_line()

or the "mid-loop break" model, which is what makes this similar to the above:

while True:
    line = get_next_line()
    if line==".": break
    process_line(line)

There's no nice way to spell "grab this and retain it". But again, I'm
not sure how a change of indentation could improve this.

>> That structure makes no sense to me. Why is the "break_when" *outside* of
>> the loop? Why does the "break_when condition" introduce a new block?
>
> How do you mean outside the loop? Do you consider the "else" outside the
> if statement?

The "break_when" is part of the loop structure, not the loop body.
With an entry-checked condition, the loop structure is flush left, and
the loop body is indented:

x, y = 0, 1
while x < y:
    x = (x + y) / 2
    y = f(x)

Some languages have a similar construct for an exit-checked condition, eg REXX:

do until x > y
    /* as above */
end

or BASIC-derived languages:

do
    rem as above
loop while x < y

In all three cases, the condition is on a line that's not indented. So
logically, the mid-checked loop could also go flush left:

do
    some code
while condition
    more code
end

Whether this actually improves readability or not is a separate
question. The "break_when" isn't so much *outside* the loop as simply
*not inside* the loop.

ChrisA



More information about the Python-list mailing list