__next__ is the iterator method that produces one value per call. It returns the next item or raises StopIteration when iteration is finished; Python’s next() built-in invokes it. section 11.1 section 11.2
Implementing __next__ requires a small state machine:
- Store iteration state, such as the current index, on the iterator object because method-local state does not survive between calls. section 11.7
- Check whether more values remain before indexing into the data. section 11.3
- Return one value and advance the state after each successful call. section 11.3
- Raise StopIteration rather than returning a sentinel when no values remain; a for loop then exits. section 11.13 section 11.2
A stateful iterator
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 receives a, b, and c, then stops when __next__ raises StopIteration. section 11.3
Table 11.1 What you need to know
|
Concept
|
What is it?
|
Example
|
To learn more
|
|---|---|---|---|
iter
|
A built-in function that returns an object’s iterator
|
iter('abcd')
|
|
next
|
A built-in function that requests the next object from an iterator
|
next(i)
|
|
StopIteration
|
An exception raised to indicate the end of a loop
|
raise StopIteration
|
|
enumerate
|
Helps us to number elements of iterables
|
for i, c in enumerate('ab'):
print(f'{i}: {c}')
|
|
|
Iterables
|
A category of data in Python
|
Iterables can be put in
for loops or passed to many functions.
|
|
itertools
|
A module with many classes for implementing iterables
|
import itertools
|
|
range
|
Returns an iterable sequence of integers
|
# every 3rd integer, from 10
# to (not including) 50
range(10, 50, 3)
|
|
os.listdir
|
Returns a list of files in a directory
|
os.listdir('/etc/')
|
|
os.walk
|
Iterates over the files in a directory
|
os.walk('/etc/')
|
|
yield
|
Returns control to the loop temporarily, optionally returning a value
|
yield 5
|
|
os.path.join
|
Returns a string based on the path components
|
os.path.join('etc', 'passwd')
|
|
time.perf_ counter |
Returns the number of elapsed seconds (as a float) since the program was started
|
time.perf_counter()
|
|
zip
|
Takes
n iterables as arguments and returns an iterator of tuples of length
n
|
# returns [('a', 10),
# ('b', 20), ('c', 30)]
zip('abc',
[10, 20, 30])
|
Use the iterator reference table to compare __next__ with next(), iterables, StopIteration, enumerate, itertools, and range. section 11.5
An iterable need only provide __iter__, which returns an iterator. The iterator may be the iterable itself or a separate object; separate iterators allow repeated loops to start with fresh state. section 11.5 section 11.7

