Python

Python Basics

Data Structures in Python

Control Flow and Loops

Functions and Scope

Python Core Concepts

Python Collections

Python Programs

Understanding Iterators and Iterables in Python

In Python, looping through data is a common task. Whether you’re working with lists, dictionaries, files, or even database results, you’ll almost always need to iterate over data. To do that, Python uses two core concepts: iterators and iterables.

If you’ve used a for loop in Python, you’ve already worked with iterators and iterables — even if you didn’t realize it. In this article, we’ll break down these concepts in a clear, non-technical way so that even absolute beginners can grasp and use them confidently.


📌 Why Are Iterators and Iterables Important?

Python is a language built for readability and simplicity. Iterators and iterables power many of its most elegant features, including:

  • Looping (for loops)
  • Lazy evaluation
  • Generators
  • Efficient memory usage (especially for large datasets)

Without understanding how iterators and iterables work, you might find it harder to write optimized, readable Python code — or troubleshoot loop-related bugs.


✅ Prerequisites

Before diving in, make sure you’re familiar with:

  • Python variables
  • Basic data types (like lists and strings)
  • for and while loops
  • Functions and methods

If you’ve written a basic for item in list: loop, you’re ready to explore iterators and iterables!


🧭 What This Guide Covers

  1. What is an Iterable?
  2. What is an Iterator?
  3. How the for Loop Uses Iterators
  4. The iter() and next() Functions
  5. Creating a Custom Iterator Class
  6. Key Differences Between Iterators and Iterables
  7. Real-World Examples
  8. Common Mistakes
  9. Best Practices

🔄 What is an Iterable?

An iterable is any Python object capable of returning its members one at a time. That means you can “iterate” over it — for example, using a for loop.

Common examples of iterables:

  • Lists ([1, 2, 3])
  • Tuples ((1, 2, 3))
  • Strings ("hello")
  • Dictionaries ({"a": 1, "b": 2})
  • Sets ({1, 2, 3})
  • Files (line by line)

Any object is considered iterable if it implements the __iter__() method, which returns an iterator.


🔁 What is an Iterator?

An iterator is an object that keeps track of where it is in a sequence. It knows how to return the next value when requested.

In Python, an object is considered an iterator if it has:

  • An __iter__() method that returns the object itself
  • A __next__() method that returns the next item or raises StopIteration if there are no more items

🔍 How Does a for Loop Use Iterators?

When you write a loop like this:

for letter in "cat":
    print(letter)

Here’s what happens behind the scenes:

  1. Python calls "cat".__iter__() to get an iterator.
  2. It then repeatedly calls iterator.__next__() to get each letter.
  3. Once the sequence is exhausted, StopIteration is raised, and the loop ends.

🛠 Using iter() and next()

Python provides two built-in functions to manually work with iterators:

  • iter(object) — converts an iterable into an iterator
  • next(iterator) — fetches the next item from the iterator

Example:

numbers = [1, 2, 3]
it = iter(numbers)
print(next(it))  # Output: 1
print(next(it))  # Output: 2
print(next(it))  # Output: 3

If you call next(it) again, you’ll get a StopIteration error.


🧱 Creating a Custom Iterator

You can also create your own iterator using a class.

Example: A Countdown Iterator

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

cd = Countdown(3)
for num in cd:
    print(num)

Output:

3
2
1

This is helpful when you want to create custom looping behavior, like generating sequences or streaming data.


🔄 Iterators vs Iterables: Key Differences

FeatureIterableIterator
Has __iter__()✅ Yes✅ Yes
Has __next__()❌ No✅ Yes
Can be looped using for✅ Yes✅ Yes
Remembers position❌ No✅ Yes
Examplelist, striter(list)

In short:

  • Iterable: Can be looped over
  • Iterator: Can fetch the next item

✅ Real-World Examples

Example 1: File Reading (Line by Line)

with open("example.txt") as file:
    for line in file:
        print(line.strip())

Why It Works: Files are iterable; each line is returned using an internal iterator.


Example 2: Iterating with iter() and next()

data = ['a', 'b', 'c']
it = iter(data)
while True:
    try:
        print(next(it))
    except StopIteration:
        break

Use Case: Manual iteration gives more control over loop behavior.


Example 3: Lazy Evaluation with range()

r = range(1000000)
print(next(iter(r)))

Why Important: range is a memory-efficient iterable that doesn’t store all numbers in memory.


Example 4: Looping Through a Dictionary

my_dict = {'a': 1, 'b': 2}
for key in my_dict:
    print(key, my_dict[key])

Behind the Scenes: The dictionary creates an iterator over its keys.


Example 5: Creating an Infinite Iterator

def infinite_numbers():
    num = 1
    while True:
        yield num
        num += 1

for i in infinite_numbers():
    if i > 5:
        break
    print(i)

Explanation: This is a generator (a type of iterator) that produces an endless stream of numbers.


❗ Common Mistakes to Avoid

  • Trying to reuse an exhausted iterator
  • Confusing iterators and iterables
  • Forgetting to handle StopIteration
  • Assuming all data structures are both iterable and iterators (they’re not!)

🌟 Best Practices

  • Use for loops for simple iteration — they handle everything internally.
  • Use iter() and next() when you need fine control.
  • Avoid manually calling __next__(); use next() instead.
  • Use generators when you want lazy evaluation or infinite streams.
  • Don’t mix up iterables and iterators — they serve different roles.

Understanding the difference between iterables and iterators is essential for writing efficient, Pythonic code. From reading files and looping through data to building your own custom data processors, iterators offer the flexibility and control needed for serious Python development.

By mastering these concepts, you’re not only gaining better insight into Python’s inner workings but also preparing yourself to tackle more advanced topics like generators, coroutines, and async programming.