How to Differentiate Iterator and Generator in Python

Jesse John Feb 02, 2024
  1. Iterator in Python
  2. Generator in Python
  3. Examples of Iterator and Generator in Python
  4. Conclusion
How to Differentiate Iterator and Generator in Python

Iterators and generators help us generate some output or process some code iteratively, one bit at a time. In this article, we will learn some basic differences between Python’s iterators and generators with a simple example.

Iterator in Python

The basic features of an iterator are as follows:

  1. An iterator is an object created using a class that implements the iterator protocol. This means that the class has __iter__ and __next__ methods defined.
  2. The __next__ method uses the return statement to return a value. Since the return statement must be the last line in that method, we must update the variable to be used in the next run of __next__ before the return statement.

In the simplest case, we will look at, __iter__ returns self.

Generator in Python

The basic features of a generator are as follows:

  1. A generator is a function.
  2. A generator function uses the yield keyword instead of the return keyword.
    2.1 The yield keyword yields a value and suspends the function’s execution.
    2.2 The next call to next() resumes the execution of the code after the yield statement.

A generator function allows us to create a generator iterator without all the extra code required when creating an iterator using a class.

Examples of Iterator and Generator in Python

The following two examples highlight the points mentioned in the previous two sections. Both examples illustrate how to generate squares of integers, starting with 1.

The first example shows how it is done using an iterator. The second example shows equivalent code using a generator.

Example Code for Iterator:

# ITERATOR (Class)


class squares(object):
    def __init__(self, num1):
        self.nxt_sq_of = 1
        self.lim = num1

    def __iter__(self):
        return self

    def __next__(self):

        if self.nxt_sq_of <= self.lim:
            ret_sq_of = self.nxt_sq_of
            self.nxt_sq_of += 1
            return ret_sq_of * ret_sq_of
        else:
            raise StopIteration


# Iterator Object
a = squares(6)

# Next value of the iterator.
next(a)
next(a)
next(a)
next(a)
next(a)
next(a)
next(a)
next(a)


# Using the iterator in a loop.
a1 = squares(6)

while True:
    print(next(a1))

Output:

next(a)
Out[3]: 1

next(a)
Out[4]: 4

next(a)
Out[5]: 9

next(a)
Out[6]: 16

next(a)
Out[7]: 25

next(a)
Out[8]: 36

next(a)
Traceback (most recent call last):

  File "<ipython-input-9-15841f3f11d4>", line 1, in <module>
    next(a)

  File "<ipython-input-1-9dbe8e565876>", line 17, in __next__
    raise StopIteration

StopIteration

Example Code for Generator:

# GENERATOR FUNCTION


def gen_squares(num2):
    i = 1
    while i <= num2:
        yield i * i
        i += 1


# Generator iterator.
b = gen_squares(5)

# Next yield of the generator iterator.
next(b)
next(b)
next(b)
next(b)
next(b)
next(b)

Output:

next(b)
Out[3]: 1

next(b)
Out[4]: 4

next(b)
Out[5]: 9

next(b)
Out[6]: 16

next(b)
Out[7]: 25

next(b)
Traceback (most recent call last):

  File "<ipython-input-8-adb3e17b0219>", line 1, in <module>
    next(b)

StopIteration

Conclusion

We find that Python’s generators allow us to write concise code to create a generator iterator.

Iterators, on the other hand, are much more powerful because they allow the programmer to write custom code for the __iter__ method.

For more details, refer to the following.

  1. Python Wiki article for generators.
  2. Python Wiki article for iterators.
Author: Jesse John
Jesse John avatar Jesse John avatar

Jesse is passionate about data analysis and visualization. He uses the R statistical programming language for all aspects of his work.

Related Article - Python Iterator

Related Article - Python Generator