Skip to content
On this page

Iterator

We already know that the following data types can be directly used in a for loop:

  1. Collection data types: such as list, tuple, dict, set, str, etc.
  2. Generators: including generator expressions and generator functions with yield.

These objects that can be directly used in a for loop are collectively referred to as iterable objects: Iterable.

You can use isinstance() to determine whether an object is an Iterable:

python
>>> from collections.abc import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False

While generators can not only be used in for loops but can also be repeatedly called with the next() function to return the next value until a StopIteration error is raised, indicating that no further values can be returned, those objects that can be called by the next() function and can continuously return the next value are called iterators: Iterator.

You can use isinstance() to check if an object is an Iterator:

python
>>> from collections.abc import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False

Generators are Iterator objects, but list, dict, and str are Iterable but not Iterator.

You can convert Iterable types like list, dict, and str into Iterator using the iter() function:

python
>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True

You might wonder why list, dict, str, and other data types are not Iterators. This is because Python's Iterator object represents a data stream. An Iterator object can be called by the next() function to continuously return the next piece of data until there is no more data, at which point it raises a StopIteration error. You can think of this data stream as an ordered sequence, but we cannot know the length of the sequence in advance; we can only compute the next data as needed using the next() function. Therefore, the computation of an Iterator is lazy, meaning it is calculated only when the next data is needed.

An Iterator can even represent an infinitely large data stream, such as all natural numbers. Using a list to store all natural numbers is simply impossible.

Reference Source Code

do_iterator.py

Summary

  1. Any object that can be used in a for loop is an Iterable.
  2. Any object that can be used with the next() function is an Iterator, representing a lazily computed sequence.
  3. Collection data types like list, dict, and str are Iterable but not Iterator. However, you can obtain an Iterator object from them using the iter() function.

The for loop in Python essentially works by continuously calling the next() function, for example:

python
for x in [1, 2, 3, 4, 5]:
    pass

This is completely equivalent to:

python
# First, get the Iterator object:
it = iter([1, 2, 3, 4, 5])
# Loop:
while True:
    try:
        # Get the next value:
        x = next(it)
    except StopIteration:
        # Exit the loop when StopIteration is encountered
        break
Iterator has loaded