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