Python Iterators
An iterator is an object that produces its values one at a time, and understanding it explains how Python's for loop actually works.
Python draws a line between two related ideas. An iterable is anything you can loop over, such as a list, tuple, string, or dictionary. An iterator is the object that walks through an iterable and hands back one item each time you ask for the next one. Every time you write a for loop, Python quietly creates an iterator behind the scenes and calls it repeatedly until there is nothing left.
iter() and next()
You turn an iterable into an iterator with the built-in iter() function, then pull values from it with next(). When the iterator runs out of items, next() raises a StopIteration exception, which is the signal a for loop uses to know it should stop.
Stepping through an iterator by hand
colors = ["red", "green", "blue"]
it = iter(colors)
print(next(it)) # red
print(next(it)) # green
print(next(it)) # blue
# print(next(it)) would now raise StopIterationWhat a for loop really does
A for loop is simply a convenient wrapper around iter() and next(). The two snippets below behave identically; the loop just hides the exception handling for you.
The for loop, expanded
numbers = [1, 2, 3]
# What you write:
for n in numbers:
print(n)
# What Python effectively does:
it = iter(numbers)
while True:
try:
n = next(it)
except StopIteration:
break
print(n)Building your own iterator
You can make any class iterable by defining two special methods. __iter__() returns the iterator object itself, and __next__() returns the next value or raises StopIteration when finished. The class below counts up to a limit you choose.
A custom iterator class
class CountUpTo:
def __init__(self, limit):
self.limit = limit
self.current = 1
def __iter__(self):
return self
def __next__(self):
if self.current > self.limit:
raise StopIteration
value = self.current
self.current += 1
return value
for number in CountUpTo(4):
print(number) # prints 1, 2, 3, 4Exercise: Python Iterators
Which two special methods must an object define to be an iterator?