generator comprehension
Python programming
Python generators
coding
programming concepts

How does a generator comprehension works?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

A generator comprehension in Python creates an iterator that yields values only when needed. It looks similar to a list comprehension, but it does not materialize all results at once. This lazy behavior is ideal for pipelines, large files, and memory-sensitive workloads.

Core Sections

Syntax and execution model

Generator comprehension syntax uses parentheses instead of brackets. The expression is not fully evaluated at creation time. Computation happens as values are consumed.

python
1squares = (n * n for n in range(5))
2print(squares)      # generator object
3print(next(squares))
4print(next(squares))
5
6for value in squares:
7    print(value)

The first two next calls consume values. The for loop then continues from the current position, not from the beginning. This behavior is correct but often surprising to developers who expect list-like reuse.

Single-pass iteration and exhaustion

A generator can be consumed only once. After exhaustion, iterating again produces no values unless you construct a new generator.

python
1gen = (x for x in [1, 2, 3])
2print(list(gen))  # [1, 2, 3]
3print(list(gen))  # []
4
5# Rebuild to iterate again
6gen = (x for x in [1, 2, 3])
7print(sum(gen))   # 6

This single-pass design is why generators are memory efficient. They keep only iteration state, not the full result set.

Building lazy pipelines

Generator comprehensions compose well. You can chain filtering, mapping, and aggregation while keeping every stage lazy.

python
1def read_numbers(path: str):
2    with open(path, 'r', encoding='utf-8') as f:
3        for line in f:
4            line = line.strip()
5            if line:
6                yield int(line)
7
8numbers = read_numbers('numbers.txt')
9even_numbers = (n for n in numbers if n % 2 == 0)
10scaled = (n * 10 for n in even_numbers)
11
12print(sum(scaled))

In this pipeline, only one line is processed at a time. That matters when files are large or produced continuously.

When to use list comprehensions instead

Use list comprehensions when you need random access, repeated iteration, or debugging visibility of all intermediate values.

python
1values = [n * n for n in range(10)]
2print(values[3])
3print(values[3:6])
4print(sum(values))

Use generator comprehensions when you stream forward once. Use list comprehensions when you need collection behavior. Both tools are useful, and choosing based on access pattern keeps code both fast and maintainable.

Practical performance check

A quick benchmark can verify whether lazy evaluation helps your case.

python
1import time
2
3N = 2_000_000
4
5start = time.perf_counter()
6result_gen = sum(x * x for x in range(N))
7mid = time.perf_counter()
8result_list = sum([x * x for x in range(N)])
9end = time.perf_counter()
10
11print(result_gen, f"generator time: {mid - start:.3f}s")
12print(result_list, f"list time: {end - mid:.3f}s")

Results vary by workload and hardware, but generator style usually reduces peak memory. Always measure with realistic data before standardizing one pattern across a codebase.

Generator comprehensions are also useful at API boundaries where one component produces records and another component consumes them progressively. This keeps backpressure behavior explicit and limits memory spikes during bursts. When troubleshooting slow pipelines, add timing around each consumption stage rather than only around generator creation. Most latency appears when values are pulled, not when the generator object is declared.

Common Pitfalls

  • Expecting generator results to be reusable after one full iteration.
  • Assuming generator creation performs all work immediately.
  • Using generators when random indexing is required later.
  • Hiding side effects inside generator expressions and making flow hard to trace.
  • Converting to a list too early and losing the memory benefit.

Summary

  • Generator comprehensions are lazy iterators built with parentheses.
  • Values are computed on demand and consumed in a single pass.
  • Composing generators is effective for stream-style data processing.
  • Lists remain the better choice for random access and repeated traversal.
  • Benchmark with realistic inputs to choose the right approach.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.