Python Tutorial › Functions › Iterators

Python Iterators

IntermediateLesson 28 of 479 min read8 runnable examples

Every for loop in Python uses an iterator behind the scenes. Knowing how iterators work explains why some objects can be looped over only once, and lets you write your own objects that work with for.

Advertisement
In this lesson
  • Iterables vs iterators
  • iter(), next() and StopIteration
  • Build a custom iterator class
  • Useful tools from itertools

Iterable vs iterator

  • An iterable is anything you can loop over: a list, string, tuple, dict, set, file or range.
  • An iterator is the object that actually hands out the items, one at a time, and remembers its position.

iter() gets an iterator from an iterable, and next() asks it for the next item:

Python
colors = ["red", "green", "blue"]it = iter(colors) print(next(it))print(next(it))print(next(it))
Output
red
green
blue

When there are no items left, next() raises StopIteration:

Python
it = iter([1])print(next(it))print(next(it))
Output
1
Traceback (most recent call last):
  File "main.py", line 3, in <module>
    print(next(it))
          ~~~~^^^^
StopIteration

Pass a default to next() to avoid the error:

Python
it = iter([])print(next(it, "no more items"))
Output
no more items

How a for loop works

A for loop is a while loop that calls iter() once and next() until StopIteration:

Python
items = ["a", "b", "c"] it = iter(items)while True:    try:        item = next(it)    except StopIteration:        break    print(item)
Output
a
b
c

Iterators are used up

An iterator moves forward only. Once it is exhausted it stays empty. A list can be looped over many times because each for loop asks it for a fresh iterator.

Python
squares = map(lambda x: x * x, [1, 2, 3])    # map returns an iteratorprint(list(squares))print(list(squares))      # already used up nums = [1, 2, 3]print(sum(nums), sum(nums))   # a list gives a new iterator each time
Output
[1, 4, 9]
[]
6 6

Write your own iterator

A class becomes an iterator by defining __iter__() (returning itself) and __next__() (returning the next item or raising StopIteration):

Python
class Countdown:    def __init__(self, start):        self.current = start     def __iter__(self):        return self     def __next__(self):        if self.current <= 0:            raise StopIteration        value = self.current        self.current -= 1        return value for n in Countdown(3):    print(n)print(list(Countdown(5)))
Output
3
2
1
[5, 4, 3, 2, 1]
Tip

Writing a class like this takes a dozen lines. A generator function does the same job in three; see the next lesson, Generators.

Infinite iterators and itertools

Iterators can be infinite because they produce values only when asked. The itertools module has many ready-made ones:

Python
import itertools counter = itertools.count(start=100, step=10)print([next(counter) for _ in range(3)]) print(list(itertools.islice(itertools.cycle("AB"), 5)))print(list(itertools.chain([1, 2], (3, 4), "56")))print(list(itertools.combinations("ABC", 2)))print(list(itertools.product([0, 1], repeat=2)))
Output
[100, 110, 120]
['A', 'B', 'A', 'B', 'A']
[1, 2, 3, 4, '5', '6']
[('A', 'B'), ('A', 'C'), ('B', 'C')]
[(0, 0), (0, 1), (1, 0), (1, 1)]

Built-ins that return iterators

map(), filter(), zip(), enumerate(), reversed() and open() all return iterators. They are lazy: no work happens until you ask for items.

Python
pairs = zip(["a", "b", "c"], [1, 2, 3])print(next(pairs))print(list(pairs))       # continues from where next() left off
Output
('a', 1)
[('b', 2), ('c', 3)]

Check your understanding

Predict the output

it = iter("abc")next(it)print(list(it), list(it))

Quick quiz

1. Which function gets the next item from an iterator?

2. What happens when an iterator has no more items?

3. Which two methods make a class an iterator?

Exercise: even number iterator

Write a class Evens(limit) that iterates over the even numbers from 0 up to and including limit.

Input
Evens(10)
Expected output
[0, 2, 4, 6, 8, 10]
Hint 1

Store the next value in self.n and add 2 each time.

Program Practice

20 Python Iterator & Generator Programs

Every program has a step-by-step explanation, colour-coded code and its real output.

Start practising →
Related sets:All practice sets

Python iterators FAQ

What is the difference between an iterable and an iterator?

An iterable can produce an iterator (lists, strings, dicts). An iterator produces the items one at a time with next() and remembers its position. Every iterator is also iterable.

Why can I loop over a list twice but not over map()?

A list creates a new iterator for each loop. map() is itself an iterator, so once its items are consumed it is empty.

How do I make a class iterable in Python?

Define __iter__() returning an iterator. The easiest way is to make __iter__ a generator method using yield.

Leave a Comment