470,591 Members | 2,162 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,591 developers. It's quick & easy.

Counting nested loop iterations

What is the best way to count nested loop iterations? I can only figure
to use an index but that seems kludgy.

index = 0
for animal in zoo:
for color in animal:
index += 1

Thanks,
Derek Basch

Mar 16 '06 #1
18 3512
Derek Basch wrote:
What is the best way to count nested loop iterations? I can only figure
to use an index but that seems kludgy.

index = 0
for animal in zoo:
for color in animal:
index += 1


what's kludgy with using a counter to count things ?

(the real question here is of course why you need the counter. what's
the loop doing? if the code you posted is all you have, you can replace
it with index = sum(len(animal) for animal in zoo), but I assume you want
to do more stuff in there...)

</F>

Mar 16 '06 #2
Derek Basch wrote:
What is the best way to count nested loop iterations? I can only figure
to use an index but that seems kludgy.

index = 0
for animal in zoo:
for color in animal:
index += 1


Depending on the types of the containers in question, you could use:

len(zoo) * len(animal)

Mar 16 '06 #3

Fredrik Lundh wrote:
what's kludgy with using a counter to count things ?
Ohhh, nothing in particular. Just seeing if there is a better way to do
it.
(the real question here is of course why you need the counter. what's
the loop doing? if the code you posted is all you have, you can replace
it with index = sum(len(animal) for animal in zoo), but I assume you want
to do more stuff in there...)

</F>


Yes, I am doing more. Your example assumes that all that animals have
the same amount of colors. Not a bad assumption considering I didn't
say anything about that. Looks like good old counters are they way to
go then.

Mar 16 '06 #4
> Depending on the types of the containers in question, you could use:

len(zoo) * len(animal)


I think this would give me the total iterations but I wouldn't be able
to get a running count. Correct?

Thanks for the reply,
Derek Basch

Mar 16 '06 #5
Hi Derek

I went for an embarrassingly long time without knowing about
"enumerate()". It doesn't directly answer your question about counting
*within* nests, but I am going to tell you this on the off chance you
don't know yet (and apologies if you do):

This:

count = 0
for animal in zoo:
a = animal
anum = count
count = count + 1

IS a kludge, when you have this available to you:

for count, animal in enumerate(zoo):
a = animal
anum = count

I won't say how long it took me to start using list comprehensions :)

regards
Caleb

Mar 16 '06 #6
Derek Basch wrote:
Fredrik Lundh wrote:
(the real question here is of course why you need the counter. what's
the loop doing? if the code you posted is all you have, you can replace
it with index = sum(len(animal) for animal in zoo), but I assume you want
to do more stuff in there...)

</F>

Yes, I am doing more. Your example assumes that all that animals have
the same amount of colors.


No, it doesn't. Fredrik wrote
index = sum(len(animal) for animal in zoo)

The expression (len(animal) for animal in zoo) yields a sequence of the
lengths of the individual animals; passing this to sum() gives the total
count.

Kent
Mar 16 '06 #7
Derek Basch wrote:
index = 0
for animal in zoo:
for color in animal:
index += 1 # assuming there is something more goes here...


You could do this, but it kind of depends what the loop *really* looks
like:

for index, color in enumerate(color
for animal in zoo
for color in animal):
# the something more goes here.
pass
Mar 16 '06 #8
Derek Basch wrote:
What is the best way to count nested loop iterations? I can only figure
to use an index but that seems kludgy.

index = 0
for animal in zoo:
for color in animal:
index += 1


I don't know if it's kludgy, but I do prefer to set counters in the for
statement whenever I can. If I were using 2.4, I might try writing
something like:

for i,(animal,zoo) in enumerate((animal,zoo) for animal in zoo for
color in animal):
pass

or maybe break it down a little for clarity:

aciter = ((animal,zoo) for animal in zoo for color in animal)
for i,(animal,zoo) in enumerate(aciter):
pass

But even the clear version isn't as nearly clear and straightforward as
the nested fors with the counter. I wouldn't forsake that clarity just
so it isn't "kludgy".
Carl Banks

Mar 16 '06 #9

Carl Banks wrote:
But even the clear version isn't as nearly clear and straightforward as
the nested fors with the counter. I wouldn't forsake that clarity just
so it isn't "kludgy".
Carl Banks


Yeah, looks like using the counters is clearer. Thanks for the opinions
everyone!

Derek Basch

Mar 16 '06 #10
Derek Basch wrote:
Depending on the types of the containers in question, you could use:

len(zoo) * len(animal)


I think this would give me the total iterations but I wouldn't be able
to get a running count. Correct?


Correct. If you need a running count, maintain a counter (or enumerate()).
Mar 16 '06 #11
> for index, color in enumerate(color
for animal in zoo
for color in animal):
# the something more goes here.
pass


I've been thinking about these nested generator expressions and list
comprehensions. How come we write:

a for b in c for a in b

instead of

a for a in b for b in c

More detailed example follows below.

I feel the latter variant is more intuitive. Could anyone please explain the
fault of my logic or explain how I should be thinking about this? Or point me
to somewhere where I can read up on this?

Cheers,
Joel Hedlund

More detailed example:
c = [[1,4,8],[2,5,7]]
[a for b in c for a in b] [1, 4, 8, 2, 5, 7] del a,b,c
c = [[1,4,8],[2,5,7]]
[a for a in b for b in c]


Traceback (most recent call last):
File "<pyshell#30>", line 1, in -toplevel-
[a for a in b for b in c]
NameError: name 'b' is not defined

Mar 17 '06 #12
Joel Hedlund wrote:
I've been thinking about these nested generator expressions and list
comprehensions. How come we write:

a for b in c for a in b

instead of

a for a in b for b in c

More detailed example follows below.

I feel the latter variant is more intuitive. Could anyone please explain the
fault of my logic or explain how I should be thinking about this?


out = [a for b in c for a in b]

can be written

out = [a
for b in c
for a in b]

which is equivalent to

out = []
for b in c:
for a in b:
out.append(a)

in other words, a list comprehension works exactly like an ordinary for
loop, except that the important thing (the expression) is moved to the
beginning of the statement.

</F>

Mar 17 '06 #13
> a list comprehension works exactly like an ordinary for
loop, except that the important thing (the expression) is moved to the
beginning of the statement.


Right. Thanks!
/Joel
Mar 17 '06 #14
Fredrik Lundh wrote:
Joel Hedlund wrote:
I've been thinking about these nested generator expressions and list
comprehensions. How come we write:

a for b in c for a in b

instead of

a for a in b for b in c

More detailed example follows below.

I feel the latter variant is more intuitive. Could anyone please explain the
fault of my logic or explain how I should be thinking about this?


out = [a for b in c for a in b]

can be written

out = [a
for b in c
for a in b]

which is equivalent to

out = []
for b in c:
for a in b:
out.append(a)

in other words, a list comprehension works exactly like an ordinary for
loop, except that the important thing (the expression) is moved to the
beginning of the statement.


Which is utterly counter-intuitive, the opposite of Perl, and remains
one of the most confusing and surprising things I have encountered in
Python so far.

And nobody start yelling that Python is not Perl. We all know Python is
not Perl, nor should it be. If you want different for the sake of
different, though, go try MOO or something. Here:

http://en.wikipedia.org/wiki/Esoteri...mming_language
Mar 17 '06 #15
> Which is utterly counter-intuitive, the opposite of Perl, and remains
one of the most confusing and surprising things I have encountered in
Python so far.


AFAIK stems from mathematics where you write things like

{y | \forall x \in X : \forall y \in x }

And so many people consider it pretty natural/intuitive. After all, we read
from left to right, and making something depend from something yet to be
introduced is counter-intuitive in my book. YMMV though.

Diez

Mar 17 '06 #16
Diez B. Roggisch wrote:
Which is utterly counter-intuitive, the opposite of Perl, and remains
one of the most confusing and surprising things I have encountered in
Python so far.


AFAIK stems from mathematics where you write things like

{y | \forall x \in X : \forall y \in x }

And so many people consider it pretty natural/intuitive. After all, we
read from left to right, and making something depend from something
yet to be introduced is counter-intuitive in my book. YMMV though.

I think the problem is that y is used before the loop which creates it, but
x is used after the loop which creates it.

People can cope with the expanded loop form where everything it is used
after it is introduced, and it would appear that they also cope well with
the perl way of doing everything backwards, but moving the last element to
the front while keeping everything else in the 'correct' order seems to
confuse a lot of people.

Oh well, just wait until Python 2.5 comes out and we get people complaining
about the order of the new if statement.
Mar 17 '06 #17
> I think the problem is that y is used before the loop which creates it,
but x is used after the loop which creates it.
Well, you got me on that. Seems to be a matter of convention all the time.
People can cope with the expanded loop form where everything it is used
after it is introduced, and it would appear that they also cope well with
the perl way of doing everything backwards, but moving the last element to
the front while keeping everything else in the 'correct' order seems to
confuse a lot of people.

Oh well, just wait until Python 2.5 comes out and we get people
complaining about the order of the new if statement.


Sad, but true. But I'm a happy camper with list-comps and the new
if-expression :)

Diez
Mar 17 '06 #18
Duncan Booth wrote:
Oh well, just wait until Python 2.5 comes out and we get people complaining
about the order of the new if statement.


Or rather, the order of the new if _expression_.

--Scott David Daniels
sc***********@acm.org
Mar 17 '06 #19

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

25 posts views Thread by chad | last post: by
47 posts views Thread by Mountain Bikn' Guy | last post: by
46 posts views Thread by Neptune | last post: by
7 posts views Thread by sathyashrayan | last post: by
2 posts views Thread by tony collier | last post: by
5 posts views Thread by sololoquist | last post: by
3 posts views Thread by Dieter Maurer | last post: by
13 posts views Thread by Fredrik Lundh | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.