Python – Why Do Iterators Raise an Exception

exceptionsiteratorlanguage-designpython

Here's the syntax for iterators in Java (somewhat similar syntax in C#):

Iterator it = sequence.iterator();

while (it.hasNext()) {
    System.out.println(it.next());
}

Which makes sense. Here's the equivalent syntax in Python:

it = iter(sequence)
while True:
    try:
        value = it.next() 
    except StopIteration:
        break
    print(value)

I thought Exceptions were supposed to be used only in, well, exceptional circumstances.

Why does Python use exceptions to stop iteration?

Best Answer

There's a very Pythonic way to write that expression without explicitly writing a try-except block for a StopIteration:

# some_iterable is some collection that can be iterated over
# e.g., a list, sequence, dict, set, itertools.combination(...)

for value in some_iterable:
    print(value)

You can read up on the relevant PEPs 234 255 if you want to know more behind why StopIteration was introduced and the logic behind iterators.

A general principle in python is to have one way to do something (see import this), and preferably its beautiful, explicit, readable, and simple, which the pythonic method satisfies. Your equivalent code is only necessary as python doesn't give iterators a hasNext member function; preferring people to just loop through the iterators directly (and if you need to do something else to just try reading it and catch an exception).

This automatic catching of an StopIteration exception at the end of an iterator makes sense and is an analogue of the EOFError raised if you read past an end of file.