DEV Community

Cover image for Iterator vs Generator in Python – Key Differences + Code Examples
shalini
shalini

Posted on

Iterator vs Generator in Python – Key Differences + Code Examples

If you're serious about writing efficient Python code, understanding the difference between iterators and generators is absolutely essential.

At first glance, both seem similar—they help you loop through data. But under the hood, they work very differently in terms of memory usage, execution flow, and performance.

Whether you're working on data science, backend systems, APIs, or large datasets, mastering this concept will instantly level up your Python skills.

What is Iteration in Python?

Before jumping into comparisons, let’s understand the foundation.

Iteration Definition:

Iteration means accessing elements of a collection one by one.

numbers = [1, 2, 3, 4]

for num in numbers:
    print(num)
Enter fullscreen mode Exit fullscreen mode

Behind the Scenes:

Python uses something called the iterator protocol, which includes:

✔ __iter__() → Returns iterator object
✔ __next__() → Returns next value
Enter fullscreen mode Exit fullscreen mode

Key Points:

✔ Sequential data access
✔ No need for manual indexing
✔ Works with for loops
✔ Built on iterator protocol

What is an Iterator in Python?

An iterator is an object that allows you to traverse elements one at a time.

Core Requirements:

✔ Implements __iter__()
✔ Implements __next__()
Enter fullscreen mode Exit fullscreen mode

Example:

numbers = [1, 2, 3]
Enter fullscreen mode Exit fullscreen mode
it = iter(numbers)

print(next(it))
print(next(it))
print(next(it))
Enter fullscreen mode Exit fullscreen mode

How It Works:

Keeps track of current position
Returns next value on each call
Raises StopIteration when finished

Custom Iterator Example:

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

    def __iter__(self):
        return self

    def __next__(self):
        if self.current < self.max:
            self.current += 1
            return self.current
        else:
            raise StopIteration
Enter fullscreen mode Exit fullscreen mode

Key Characteristics:

✔ Manual implementation
✔ Full control over iteration
✔ Maintains internal state
✔ Raises StopIteration
✔ More flexible but verbose

What is a Generator in Python?

A generator is a simpler way to create iterators using a function and the yield keyword.

Example:

d

ef my_generator(n):
    for i in range(n):
        yield i

gen = my_generator(3)

print(next(gen))
print(next(gen))
print(next(gen))
Enter fullscreen mode Exit fullscreen mode

How It Works:

Uses yield instead of return
Produces values one at a time
Pauses execution and resumes later
🧠 Generator Expression:
gen = (x*x for x in range(5))

for val in gen:
print(val)

Key Characteristics:

✔ Simple syntax
✔ Memory efficient
✔ Lazy evaluation
✔ Automatic iterator behavior
✔ Cleaner code

Iterator vs Generator — Core Differences

Let’s break it down clearly 👇

Creation

✔ Iterators → Created using classes
✔ Generators → Created using functions (yield)

Code Complexity

✔ Iterators → More code, more control
✔ Generators → Less code, easy to write

Memory Usage

✔ Iterators → Can use more memory
✔ Generators → Use lazy evaluation (very efficient)

Execution Flow

✔ Iterators → Controlled manually
✔ Generators → Automatically pause & resume

Performance

✔ Iterators → Good
✔ Generators → Better for large data

Quick Summary:

✔ Iterators → Control + complexity
✔ Generators → Simplicity + performance

How Generators Work Internally

Generators are powerful because they pause execution.

Example:

def demo():

print("Start")
yield 1
print("Middle")
yield 2
print("End")
Enter fullscreen mode Exit fullscreen mode

Execution Flow:

✔ Stops at yield
✔ Saves current state
✔ Resumes from same point

Key Insight:

Generators do NOT restart the function—they continue from where they paused.

Why Generators Are So Powerful

** Memory Efficiency Example:**

def get_numbers():
    for i in range(1000000):
        yield i
Enter fullscreen mode Exit fullscreen mode

👉 This does NOT store 1 million values in memory.

Benefits:

✔ Low memory usage
✔ Faster execution
✔ Ideal for large datasets
✔ Supports real-time data processing

Real-World Use Cases

** 1. Large File Processing**

def read_file(file):

with open(file) as f:
    for line in f:
        yield line
Enter fullscreen mode Exit fullscreen mode

✔ Reads file line by line
✔ No memory overload

** 2. Data Pipelines**

✔ Used in ETL pipelines
✔ Continuous data processing

3. API Pagination

✔ Fetch data in chunks
✔ Avoid loading everything at once

** 4. Infinite Sequences**

def infinite():
    i = 0
    while True:
        yield i
        i += 1
Enter fullscreen mode Exit fullscreen mode

Where Used:

✔ Backend systems
✔ Data engineering
✔ Machine learning
✔ Streaming applications

** When to Use Iterator vs Generator**
Use Iterator When:

✔ You need full control
✔ Complex logic is required
✔ Custom iteration behavior

** Use Generator When:**

✔ Working with large datasets
✔ Need memory efficiency
✔ Want clean & simple code
✔ Building pipelines

Common Mistakes Developers Make

Using List Instead of Generator

Bad:

[x for x in range(1000000)]
Enter fullscreen mode Exit fullscreen mode

Good:

(x for x in range(1000000))

Enter fullscreen mode Exit fullscreen mode

❌ Forgetting StopIteration

Important when creating custom iterators.

❌ Misusing yield

Using return instead of yield breaks generator logic.

❌ Reusing Generators

Generators cannot be reused after completion.

Best Practices (Pro Level)

Writing Better Code:

✔ Prefer generators for large data
✔ Use generator expressions
✔ Keep logic simple
✔ Avoid unnecessary memory usage
✔ Combine with itertools

Performance Tips:

✔ Use lazy evaluation
✔ Avoid loading large data into memory
✔ Use streaming approaches
✔ Optimize data flow

❓ FAQs

🔹** What is the main difference?**

Iterators are class-based and manual, while generators are function-based and automatic.

*🔹 Are generators faster?
*

✔ Yes, due to lazy evaluation and reduced memory usage.

🔹 Why use yield?

✔ It allows pausing and resuming execution.

*🔹 Can generators replace iterators?
*

✔ In most cases, yes.

** Conclusion**

Understanding Iterator vs Generator in Python is crucial for writing high-performance and scalable applications.

✔ Iterators → Powerful but complex
✔ Generators → Simple, efficient, and modern

Final Takeaway:

Use generators whenever possible for better performance
Use iterators when you need full control
Practice both to become a professional Python developer

Pro Tip: Start replacing large lists with generators in your current projects—you’ll instantly see performance improvements.

Top comments (0)