liveBook · Manning

StopIteration

As explained in Python Workout, Second Edition

StopIteration is the Python exception raised by an exhausted iterator to signal that no more values are available.

StopIteration is the exception an exhausted iterator raises to signal that no values remain. A for loop catches this signal and exits instead of requiring an index. section 11.1 section 11.2

Use StopIteration as the termination part of Python’s iterator protocol:

  • Implement __iter__ to return an iterator, then let repeated __next__ calls produce values. section 11.2
  • Raise StopIteration when the iterator has reached the end; the surrounding for loop then exits. section 11.3
  • Track iteration state on the object, such as self.index, because __next__ must preserve progress between calls. section 11.7
  • Do not explicitly raise StopIteration inside a generator; reaching the function’s end raises it automatically, while return exits the generator. section 11.17

A custom iterator reaches the end

class LoudIterator: def __init__(self, data): self.data = data self.index = 0 def __iter__(self): return self def __next__(self): if self.index >= len(self.data): raise StopIteration value = self.data[self.index] self.index += 1 return value for item in LoudIterator('abc'): print(item) The loop prints a, b, and c, then stops when __next__ raises StopIteration. section 11.3

class LoudIterator():
    def __init__(self, data):
        print('\tNow in __init__')
        self.data = data        #1
        self.index = 0     #2

    def __iter__(self):
        print('\tNow in __iter__')
        return self     #3

    def __next__(self):
        print('\tNow in __next__')
        if self.index >= len(self.data):    #4
            print(
                f'\tself.index ({self.index}) is too big; exiting')
            raise StopIteration

        value = self.data[self.index]    #5
        self.index += 1               #6
        print('\tGot value {value}, incremented index to {self.index}')
        return value


for one_item in LoudIterator('abc'):
    print(one_item)

Trace __init__, __iter__, repeated __next__ calls, state changes, and the final StopIteration signal. section 11.3

How Python Workout, Second Edition covers it

How deep it goes
Explains __iter__, __next__, stored iteration state, custom classes, and generator termination, but does not pursue advanced iterator designs fully.
Examples
Uses strings, lists, dictionaries, files, a traced LoudIterator, generator functions, and a chained generator.
What it assumes
Assumes Python functions and classes while explaining the iterator protocol through __iter__, __next__, and for loops.
What you can do after
Build iterable classes that return values from __next__ and terminate correctly with StopIteration.
How it connects
Connects StopIteration with iterables, iterators, the iterator protocol, for loops, custom classes, and generators.

Also explained in

Compare how 2 books explain StopIteration →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Python Workout, Second Edition. The section links point to the parts of the book it draws on.