Medium10 minPython Fundamentals
UpdatedAug 4, 2026
Edit

Generators and `yield`

CONCEPTS:Python Generators

Question Variations

  • "What changes when a function uses `yield` instead of `return`?"
  • "When would you choose a generator over a list?"
  • "Why can't you iterate over the same generator twice?"
  • "What is the difference between a generator expression and a list comprehension?"

Why This Is Asked

Interviewers use generators to assess your understanding of Python’s iterator protocol, lazy evaluation, and memory trade-offs. Strong answers distinguish a generator from both a list and a normal function that returns once.

Key Concepts

  • A function containing yield returns a generator object when called.
  • Values are computed on demand as the generator is advanced.
  • A generator is an iterator and is usually exhausted after one pass.
  • Lazy processing reduces peak memory use but can defer errors and repeat work.

Question Variations

  • “What changes when a function uses yield instead of return?”
  • “When would you choose a generator over a list?”
  • “Why can’t you iterate over the same generator twice?”
  • “What is the difference between a generator expression and a list comprehension?”

Answers by Technology

+ Add Variant
PythonImprove this answer ✏️

Expected Answer (Python 3.14)

A generator is a lazy iterator. Calling a generator function does not run its body to completion; it returns a generator object. Each next() call resumes execution until the next yield, preserving local state between values.

def read_nonempty_lines(lines):
    for line in lines:
        line = line.strip()
        if line:
            yield line

lines = read_nonempty_lines([" first ", "", "second"])
assert next(lines) == "first"
assert list(lines) == ["second"]

Compared with a list, a generator can process a large or unbounded input with low peak memory. The trade-off is that it is typically consumed once and each item is available only when iteration reaches it.

Why It Matters

Generators are common in file processing, pagination, streaming responses, and data pipelines. Choosing one thoughtfully can avoid loading an entire dataset into memory while keeping processing composable.

Common Mistakes

  • Expecting the function body to run when called: It begins running when the generator is first advanced.
  • Iterating over an exhausted generator again: A generator keeps its position and normally cannot be rewound.
  • Using a generator where random access is needed: Generators do not provide indexing or a known length without consuming values.

Follow-up Questions

  • What protocol makes an object iterable? (Answer: It provides __iter__() that returns an iterator; iterators also provide __next__().)
  • How does yield from help? (Answer: It delegates yielding to another iterable or generator.)