[Tutor] Determining if an iterator has more elements.

Jeff Shannon jeff@ccvcorp.com
Thu Jul 24 12:16:02 2003


Marc Barry wrote:

>
> try:
>    while(1):
>         print i.next()
> except StopIteration:
>    pass
>
> Obviously, when you run the above it prints out the values 1, 2, 3...  
> My problem is that the iterator contract in Python causes next() to 
> raise a StopIteration exception when there are no further items in the 
> iterator.  The contract provides no such method to test whether the 
> iterator has more elements (i.e. like Java's hasNext()).  Therefore, I 
> using the exception to detect when the iterator does not have anymore 
> elements.  I can't think of any other way to test for this.  I don't 
> think that exception handling is meant to be used to determine when to 
> exit a loop. 


Actually, it is -- every for-loop in Python is effectively terminated 
through exception handling.  A for loop has a hidden index variable 
that's incremented each trip through the loop; when that index variable 
is larger than the length of the sequence, an IndexError is raised.  The 
for loop implicitly catches that exception and continues execution just 
after the body of the loop.  In other words, if you were to explicitly 
write out the compiled code for a for loop, it'd have just about the 
same structure as your code snippet above.

The thing to keep in mind, here, is that Python uses exceptions much 
more freely than Java or C++, for circumstances that are much less 
exceptional.  Thus, it's considered perfectly good practice in Python 
that it's "easier to ask forgiveness than permission" -- i.e., try an 
operation and catch an exception if it fails, instead of attempting to 
check if the operation can succeed before performing the operation. 
 Catching the StopIteration exception, as you do above, is indeed 
Pythonic and accepted.

Jeff Shannon
Technician/Programmer
Credit International