Python Iterators

Python is built for readability and expressiveness. And when it comes to repeating actions or looping through data, iterators power some of Python’s most elegant features. If you’ve used a for loop in Python, you’ve already touched iterators — you just may not have realized it.

What Is an Iterator?

An iterator is an object that represents a stream of data — it returns one item at a time when you call next() on it. The iterator remembers where it left off and continues from there, making it highly efficient for looping over large datasets or infinite sequences.

Iterable vs Iterator

Before diving deeper, let’s differentiate between two terms:

  • Iterable: An object capable of returning its members one at a time. Example: lists, strings, tuples.
  • Iterator: An object which implements the __iter__() and __next__() methods. It produces values one at a time using next().

Creating an Iterator

Let’s see a simple example where we manually use an iterator.

numbers = [10, 20, 30]
iterator = iter(numbers)

print(next(iterator))  # Step 1
print(next(iterator))  # Step 2
print(next(iterator))  # Step 3
10
20
30

What Happens If You Go Too Far?

Once the iterator is exhausted, calling next() again raises a StopIteration exception.

numbers = [10, 20, 30]
iterator = iter(numbers)

print(next(iterator))  # Step 1
print(next(iterator))  # Step 2
print(next(iterator))  # Step 3
print(next(iterator))  # Raises StopIteration
1
Traceback (most recent call last):
  ...
StopIteration

Using Iterators in Loops

Typically, we don’t use next() manually. Instead, we let Python handle it through a for loop:

for char in "Hi":
    print(char)
H
i

Behind the scenes, Python does:

  1. Calls iter("Hi")
  2. Calls next() until StopIteration is raised

Custom Iterator Class

You can create your own iterator by defining a class with __iter__() and __next__() methods.

class Counter:
    def __init__(self, limit):
        self.limit = limit
        self.current = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.current >= self.limit:
            raise StopIteration
        value = self.current
        self.current += 1
        return value

count_up_to_3 = Counter(3)
for number in count_up_to_3:
    print(number)
0
1
2

Checks and Best Practices

  • Always check whether the object is iterable using hasattr(obj, '__iter__')
  • Never call next() blindly unless you handle StopIteration using a try-except block
  • Use iterators when working with large or infinite data to avoid memory bloat

How to Verify If an Object Is an Iterator?

from collections.abc import Iterator

print(isinstance(iter([1, 2, 3]), Iterator))  # True
print(isinstance([1, 2, 3], Iterator))        # False
True
False

Summary

Python iterators offer a powerful way to work with sequences efficiently. Understanding how they work under the hood gives you greater control and performance in your programs.