Python Iterators — Core Concepts

Iterators are a foundational Python concept that powers for loops, comprehensions, generators, and many standard-library tools.

If you understand the iterator protocol, many “Python magic” behaviors become straightforward.

Iterable vs Iterator

  • Iterable: an object you can loop over (list, tuple, dict, set, string, file)
  • Iterator: object that returns one item at a time and remembers state

Protocol methods:

  • iterable provides __iter__()
  • iterator provides __iter__() and __next__()

__next__() returns next item or raises StopIteration when done.

Built-ins: iter() and next()

items = ["a", "b", "c"]
it = iter(items)

print(next(it))  # a
print(next(it))  # b
print(next(it))  # c

When exhausted, next(it) raises StopIteration.

What for Loop Does Internally

Roughly equivalent logic:

it = iter(items)
while True:
    try:
        item = next(it)
    except StopIteration:
        break
    print(item)

So for is cleaner syntax around the iterator protocol.

One-Shot Nature

Many iterators are consumed once:

it = iter([1, 2, 3])
print(list(it))  # [1, 2, 3]
print(list(it))  # []

After exhaustion, you need a new iterator.

Custom Iterator Class

class CountDown:
    def __init__(self, start):
        self.current = start

    def __iter__(self):
        return self

    def __next__(self):
        if self.current <= 0:
            raise StopIteration
        value = self.current
        self.current -= 1
        return value

for n in CountDown(3):
    print(n)

This pattern is useful when stateful stepping logic does not fit standard containers.

Files Are Iterators Too

with open("app.log", "r", encoding="utf-8") as f:
    for line in f:
        if "ERROR" in line:
            print(line.strip())

Reading line-by-line via iteration is memory-friendly for large files.

Helpful Iterator Tools

itertools provides efficient building blocks:

  • islice for slicing streams
  • chain for concatenating iterables
  • zip_longest for uneven zips
  • count, cycle, repeat for infinite iterators
from itertools import islice, count

first_five = list(islice(count(10), 5))
print(first_five)  # [10, 11, 12, 13, 14]

Common Misconception

Misconception: lists and iterators are the same.

Lists are concrete collections with random access (items[2]). Iterators are streams with position, often no indexing, often one-pass.

Choosing iterator-based design can cut memory use and enable streaming pipelines.

Designing Iterator-Friendly Functions

A practical habit is to accept Iterable[T] in function inputs when random access is not required. That allows callers to pass lists, generators, file streams, or custom iterables. APIs become more reusable and easier to compose in data pipelines.

One Thing to Remember

The iterator protocol (iter + next + StopIteration) is the hidden mechanism behind Python loops and streaming data workflows.

pythoniteratorsiterator-protocolfor-loop

See Also

  • Python Async Await Async/await helps one Python program juggle many waiting jobs at once, like a chef who keeps multiple pots moving without standing still.
  • Python Basics Python is the programming language that reads like plain English — here's why millions of beginners (and experts) choose it first.
  • Python Booleans Make Booleans click with one clear analogy you can reuse whenever Python feels confusing.
  • Python Break Continue Make Break Continue click with one clear analogy you can reuse whenever Python feels confusing.
  • Python Closures See how Python functions can remember private information, even after the outer function has already finished.