Arent these snippets equivalent?

Chris Angelico rosuav at gmail.com
Wed Jan 23 23:13:14 CET 2013


On Thu, Jan 24, 2013 at 8:56 AM, Coolgg <gauravj123 at gmail.com> wrote:
> Is this:
>
> while True:
>     data = fp.read(4096)
>     if not data:
>         break
>     ...
>
> not equivalent to this:
>
> data = fp.read (4096)
> while data:
>     ...{handle the chunk here}
>     data = fp.read (4096)

They should do the same thing, but there's one critical difference in
the second: Edits to something that's really part of the loop now have
to be done twice, at the bottom of the loop and *before the loop*.
It's a violation of the principle Don't Repeat Yourself.

Personally, I'd much rather have a 'while' condition that does
assignment, but that's something Python's unlikely ever to do.
There've been various proposals to make that possible, but ultimately
the only way to make that work is for assignment to be an expression,
which is right up there alongside braces defining blocks.

(Wonder when we'll see "from __future__ import assignment_expression"
implemented...)

The 'break' method is the most common. Assuming you're doing something
as simple as the above, with a single function call and a clear
condition, it's pretty readable. Compare:

while (data = fp.read(4096))
{
    ... imagine about 20 lines here
}

and

while True:
    data = fp.read(4096)
    if not data: break
    ... imagine those same 20 lines, ported to Python

The critical parts of your while loop are in those first three lines.
It's the same goal as a C-style for loop - you can see everything you
need right up there at the loop header. All you have to do is
understand that the "loop header" is three lines long now.

With the second form of the loop, though, the loop header is down at
the bottom of the loop too. It's less clear. Granted, this might be
how a compiler lays it out in memory, but programmers shouldn't have
to read it that way.

ChrisA



More information about the Python-list mailing list