liveBook · Manning

Iterator

As explained in Python Workout: 50 ten-minute exercises

An iterator is an object that provides successive elements of an iterable, typically one element at a time.

An iterator is an object that supplies successive values, usually one at a time. Python's iterator protocol connects objects to for loops through __iter__, __next__, and StopIteration. Strings, lists, tuples, dictionaries, files, and custom objects can participate; integers cannot. section 10.0

A for loop effectively performs these steps:

A stateful iterator class

class MyIterator: 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 value in MyIterator('abc'): print(value) The object stores its position because __next__ loses local state between calls. Returning self from __iter__ is convenient, but it makes the iterator consumable: a second loop sees the exhausted position. section 10.2

When an object should support multiple independent loops, separate the iterable from a helper iterator. The iterable's __iter__ can return a fresh helper, avoiding shared index state. Other valid implementations return self, a helper instance, or a generator. section 10.2 section 10.7

Generator functions and generator expressions provide shorter ways to create iterators. They preserve execution state at yield points and can calculate values lazily, reducing memory use compared with constructing a list, especially when processing large files. section 10.26 section 7.17

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 construction, iterator acquisition, each __next__ call, index updates, returned values, and final StopIteration. section 10.0

How Python Workout: 50 ten-minute exercises covers it

How deep it goes
Explains protocol methods, stored iteration state, exhaustion, reusable helper iterators, and generator alternatives.
Examples
Demonstrates custom classes, repeated iteration, circular data, enumerate, generator expressions, and lazy file transformation.
What it assumes
Assumes familiarity with for loops while defining iterator behavior explicitly from the protocol components.
What you can do after
Builds custom iterables, writes generators, chooses reusable iterator designs, and processes data with less memory.
How it connects
Connects iterators with iterables, for loops, generators, generator expressions, enumerate, range, and itertools.

Also explained in

Compare how 15 books explain iterator →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Python Workout: 50 ten-minute exercises. The section links point to the parts of the book it draws on.