10 Iterators and generators

 

Have you ever noticed that many Python objects know how to behave inside of a for loop? That’s not an accident. Iteration is so useful, and so common, that Python makes it easy for an object to be iterable. All it has to do is implement a handful of behaviors, known collectively as the iterator protocol.

In this chapter, we’ll explore that protocol and how we can use it to create iterable objects. We’ll do this in three ways:

  1. We’ll create our own iterators via Python classes, directly implementing the protocol ourselves.
  2. We’ll create generators, objects that implement the protocol, based on something that looks very similar to a function. Not surprisingly, these are known as generator functions.
  3. We’ll also create generators using generator expressions, which look quite a bit like list comprehensions.

Even newcomers to Python know that if you want to iterate over the characters in a string, you can write

for i in 'abcd':
    print(i)      #1

This feels natural, and that’s the point. What if you just want to execute a chunk of code five times? Can you iterate over the integer 5? Many newcomers to Python assume that the answer is yes and write the following:

for i in 5:     #1
     print(i)

This code produces an error:

TypeError: 'int' object is not iterable

From this, we can see that while strings, lists, and dicts are iterable, integers aren’t. They aren’t because they don’t implement the iterator protocol, which consists of three parts:

Exercise 46 MyEnumerate

Working it out

Solution

Screencast solution

Beyond the exercise

Exercise 47 Circle

Working it out

Solution

Screencast solution

Beyond the exercise

Exercise 48 All lines, all files

Working it out

Solution

sitemap