← Back to Chapters

Python Iterators

? Python Iterators

⚡ Quick Overview

A Python iterator is an object that represents a stream of data. It returns one item at a time, allowing you to loop over it using constructs like the for loop. Iterators are useful for working with sequences without loading everything into memory at once.

Behind the scenes, iterators in Python are powered by two special methods: __iter__() and __next__().

? Key Concepts

  • An iterator is an object that can be iterated (looped) upon and remembers its state during iteration.
  • The __iter__() method returns the iterator object itself.
  • The __next__() method returns the next value from the sequence; when there are no more values, it raises StopIteration.
  • Built-in objects like lists, tuples, strings, and dictionaries are iterable and can produce iterators using the iter() function.

? Syntax and Theory

Any object that implements both __iter__() and __next__() is considered an iterator.

  • obj.__iter__() or iter(obj) is called to get an iterator from an iterable.
  • iterator.__next__() or next(iterator) is called repeatedly to fetch the next value.
  • When there are no items left, StopIteration is raised to signal the end of the iteration.

? Code Examples

? Using iter() and next() on a List

This example shows how to manually create an iterator from a list and use next() to fetch values.

? View Code Example
# A simple iterator using iter() and next()
my_list = [1, 2, 3]
my_iter = iter(my_list)

print(next(my_iter))  # 1
print(next(my_iter))  # 2
print(next(my_iter))  # 3

⚙️ Creating a Custom Iterator Class

Here we define a class that counts from a start value to an end value. The class implements __iter__() and __next__(), making it a valid iterator.

? View Code Example
class Count:
    # Iterator that counts from start to end
    def __init__(self, start, end):
        # Initialize current value and end value
        self.current = start
        self.end = end

    def __iter__(self):
        # __iter__ returns the iterator object itself
        return self

    def __next__(self):
        # __next__ returns the next number or raises StopIteration
        if self.current <= self.end:
            num = self.current
            self.current += 1
            return num
        else:
            raise StopIteration

numbers = Count(1, 5)

for num in numbers:
    # Loop over the iterator
    print(num)

? StopIteration in Action

When an iterator has no more items to return, it raises the StopIteration exception. This is how Python knows to stop a for loop.

? View Code Example
nums = iter([10, 20])

print(next(nums))  # 10
print(next(nums))  # 20
print(next(nums))  # Raises StopIteration

? Output and Explanation

▶ Example Outputs

Simple list iterator:

The code prints: 1, then 2, then 3. After the third call, the iterator is exhausted.

Custom Count iterator:

The for loop prints numbers from 1 to 5, one per line. When current becomes greater than end, StopIteration is raised, and the loop stops.

StopIteration example:

The first two calls to next(nums) return 10 and 20. The third call raises StopIteration because there are no more elements left.

? Helpful Tips

  • Iterators are memory efficient because they fetch one item at a time instead of loading everything at once.
  • Prefer using for loops to consume iterators; they automatically handle StopIteration.
  • Use built-in iterator-based functions like range(), map(), filter(), and zip() whenever possible.
  • Remember that once an iterator is exhausted, it cannot be reused unless you create a new iterator object.

? Practice Tasks

  • Create a custom iterator that returns even numbers between 1 and 20.
  • Build an iterator that generates the Fibonacci sequence up to 10 terms.
  • Use iter() and next() on a string and observe how characters are returned one by one.
  • Modify the Count class to count backwards from a start value down to 1.