Python Iterators: Understanding Iterables and Iterators in Python

← Back to Home

🔁 Understanding Python Iterators - A Simple Guide with Practical Examples


Iterators are a core concept in Python that quietly power many everyday operations. Whenever you loop over a list, read a file line by line, or work with ranges, Python is using iterators behind the scenes.

This tutorial explains Python iterators from the ground up. You’ll start with the basics and gradually move toward advanced and real-world usage, without unnecessary complexity.



✅ What Is an Iterator in Python?

An iterator is an object that returns elements one at a time instead of all at once. This makes iterators memory-efficient and ideal for handling large or continuous data.

For an object to behave as an iterator, it must implement two special methods:

  1. __iter__() – returns the iterator object itself
  2. __next__() – returns the next available value

When no more values remain, the iterator raises a StopIteration exception to signal completion.

Recommended:If you are new to Python functions, you may want to read our detailed guide on Python Functions Explained before diving deeper into generators.


🔹 Basic Example: Manually Using an Iterator


items = ["apple", "banana", "cherry"]

iterator = iter(items)

print(next(iterator))  # apple
print(next(iterator))  # banana
print(next(iterator))  # cherry

Calling next() again after the last value will result in:

StopIteration


🔍 How Python Handles Iteration in a for Loop

When you write a loop like this:


for value in [1, 2, 3]:
    print(value)

Python internally performs these steps:

  • Creates an iterator using iter()
  • Fetches values repeatedly using next()
  • Stops automatically when StopIteration is raised

This abstraction is what makes Python loops clean, readable, and efficient.



🛠️ Creating a Custom Iterator

You can define your own iterator by creating a class that implements __iter__() and __next__().

Example: Custom Number Iterator


class NumberIterator:
    def __iter__(self):
        self.current = 5
        return self

    def __next__(self):
        if self.current <= 10:
            value = self.current
            self.current += 1
            return value
        else:
            raise StopIteration

for num in NumberIterator():
    print(num)

Output:

10
11
12
13
14
15


📌 Iterable vs Iterator (Key Difference)

Iterable Iterator
Can be looped over Returns values one by one
Examples: list, tuple, string Created using iter() or custom classes
Does not define __next__() Must define __next__()


🧵 Iterating Over Strings


word = "Hi"
it = iter(word)

print(next(it))  # H
print(next(it))  # i


⚡ Why Iterators Matter

  • They consume very little memory
  • They handle large datasets efficiently
  • They enable lazy evaluation
  • They are the backbone of generators and streams


🚀 Generator Functions - A Simpler Iterator

Generators provide an easier way to create iterators using the yield keyword.

Example: Countdown Generator


def countdown(n):
    while n > 0:
        yield n
        n -= 1

for value in countdown(4):
    print(value)

Generators automatically follow the iterator protocol, making them concise and readable.

⚙️ Generator Expressions

Generator expressions work like list comprehensions but generate values on demand.


cubes = (x ** 3 for x in range(1, 6))

for c in cubes:
    print(c)

📦 Advanced Iteration with itertools

The itertools module provides optimized tools for complex iteration tasks.

Example: count()


from itertools import count

for n in count(1):
    if n > 5:
        break
    print(n)

Example: chain()


from itertools import chain

for item in chain([1, 2], ["A", "B"]):
    print(item)


📦 itertools Module - Powerful Iterator Tools

The itertools module provides built-in fast iterators, optimized tools for complex iteration tasks.

1. count() → infinite counter

from itertools import count

for n in count(3):
    if n > 8:
        break
    print(n)

2. cycle() → repeat items

from itertools import cycle

count = 0
for item in cycle(["A", "B"]):
    if count == 4:
        break
    print(item)
    count += 1

3. chain() → combine iterables

from itertools import chain

for x in chain([1, 2], ["a", "b"]):
    print(x)


📘 Real-World Uses of Iterators

  • Reading large files line by line
  • Streaming API responses
  • Processing logs or sensor data
  • Building data pipelines
  • Machine learning preprocessing


🎯 Conclusion

Iterators power the looping mechanism in Python and make data processing efficient. Whether you're building custom sequences, processing large files, or creating pipelines with generators, understanding iterators gives you a solid advantage as a Python developer.

Once you understand how iteration works internally, you gain better control over performance and memory usage.




❓ FAQs

1. Are all iterables also iterators?

No. Lists, tuples, and strings are iterables, but not iterators. They return iterators when passed to iter().

2. What is StopIteration?

It is an exception raised when an iterator has no more values to return.

3. Are generators faster than normal functions?

Yes, because they produce values one at a time rather than storing them in memory.

4. Do generators store all values?

No. They produce values one at a time, making them memory efficient.

5. Is a for loop faster than manually calling next()?

Yes. For-loops in Python are optimized internally and run faster.

6. When should I use itertools?

Use itertools when you need high-performance iteration tools or must work with large or infinite sequences.



📢 What’s Next?

If this guide helped you understand iterators, explore the next topic to level up your Python skills even further:

Practice creating your own iterators and try using generators in your own next Python script.