Loop-and-a-half (Re: Curious assignment behaviour)

Jyrinx jyrinxatmindspringdotcom
Fri Oct 12 19:02:10 EDT 2001


Erm, I'm hardly a seasoned hacker, but if I may toss in a few cents ...

> |     n = compute_number_of_items()
> |     for i in range(n):
> |        try: process_an_item(items[i])
> |        except: break
> |     update_database('number of items processed = ' % i)

Paul Rubin pointed out the problem with the empty "items" array (i never
gets initialized, exception is thrown), saying that the C way is more
concise and deals with this. Donn Cave said he doesn't like the "for x in
range()" stuff, would opt for a while loop with manual incrementation.

I like Python's for loop, "range()" idiom and all. In any case, I should
think the above code would be clearer anyway with an explicit check for an
empty list:

    n = compute_number_of_items()
    if n == 0:
        update_database('no items processed')
   else:
        for i in range(n):
           try: process_an_item(items[i])
           except: break
        update_database('number of items processed = ' % i) # (Hmm? I
thought the % operator was supposed to be used with a string and a
dictionary? Not that # I would know what I'm talking about ... :-)

Or, if you didn't want to make an extra branch and didn't want the
uninitialized-i problem, why not just initialize it to 0 before the loop?

Jyrinx
jyrinx at mindspring dot com

"Donn Cave" <donn at drizzle.com> wrote in message
news:1002866005.11653 at yabetcha.drizzle.com...
> Quoth Paul Rubin <phr-n2001d at nightsong.com>:
> ...
> | I think it's a mistake to expose too much abstract machinery in
> | Python, which is supposed to be a practical language.  Like you, I
> | don't see a need for a lot of "eyebrows" in loops, but I feel Python
> | suffers by ignoring the tried and true.
> |
> | Just today I had a bug that went something like:
> |
> |     n = compute_number_of_items()
> |     for i in range(n):
> |        try: process_an_item(items[i])
> |        except: break
> |     update_database('number of items processed = ' % i)
> |
> | The corresponding C code would have been similar except instead
> | of "for i in range(n)" it would have said "for (i=0; i<n; i++)".
> |
> | I tested the Python code on some sample data and it worked fine, so I
> | checked it in.  Then a while later it hit some real data where the
> | number of items was 0.  The C-style for loop would have initialized i
> | to 0 and then executed the loop zero times, clearly the right thing.
> | The Python for loop does this cutesy-poo set-theoretic thing instead
> | (even uselessly allocating a potentially huge block of memory unless
> | you use xrange instead of range), so that if the range is empty, i
> | never gets initialized and the update_database call throws an
> | uninitialized variable exception.  Anyway it wasn't a big deal
> | but I think Python would be improved by having a more traditional
> | loop construct.
>
> I am not a big fan of the for i in range() idiom, myself.  But you
> aren't required to use it.  If you want the effect of
>
>    for (i = 0; i<n; i++) {
>        --- do stuff --
>    }
>
> then in Python, you write
>
>    i = 0
>    while i < n:
>        --- do stuff --
>        i = i + 1
>
> "wc" says that's 7 more characters to type, which would be a concern
> if you have to engrave it on linoleum or something.  And you have to
> avoid "continue".  It seems to me this is the loop construct that people
> must use, though, if they're going to expect the tricks they learn
> in C to work.  Python's "for" loop is really a different thing, not
> something I ever found all that cutesy-poo, just a sequence thing
> that you see in plenty of languages but not C.
>
> Donn Cave, donn at drizzle.com





More information about the Python-list mailing list