Mastering Python’s Yield: Generator vs Return – A Practical Guide
What Is Python Yield?
The yield keyword behaves like return, but instead of handing back a value immediately, it returns a generator object that can be iterated over. When a function containing yield is invoked, execution pauses at the first yield statement and hands control back to the caller with a generator. Subsequent calls to next() or a for loop resume execution from that point, yielding the next value.
Key Takeaways
- Yield creates a generator, enabling lazy evaluation.
- Generators are memory‑efficient for large or infinite sequences.
- Reading from a generator can be done with
for‑in,list(), ornext(). - Once exhausted, a generator cannot be reused; call the function again.
Syntax
yield expression
Practical Example: A Simple Yield
def test_yield():
yield "Welcome to Guru99 Python Tutorials"
output = test_yield()
print(output)
Output:
<generator object test_yield at 0x00000028265EB9A8>
The generator object holds the yielded value. To access it, iterate:
for value in output:
print(value)
Output:
Welcome to Guru99 Python Tutorials
Generators Explained
A generator function is a special function that returns an iterable generator object. Unlike regular functions that return a single value, a generator yields a sequence of values lazily, producing each one only when requested.
Creating a Generator Function
def generator_example():
yield "H"
yield "E"
yield "L"
yield "L"
yield "O"
for letter in generator_example():
print(letter)
Output:
H E L L O
Normal Function vs Generator Function
Consider the following pair of functions:
# Normal function
def normal_test():
return "Hello World"
# Generator function
def generator_test():
yield "Hello World"
print(normal_test()) # → Hello World
print(generator_test()) # → <generator object generator_test>
Normal functions terminate at return; generators pause at yield, returning control to the caller with a generator object.
Consuming a Generator
You can pull values from a generator using:
for‑inloopslist()to materialize all valuesnext()for manual stepping
Example: Even Numbers
def even_numbers(n):
for x in range(n):
if x % 2 == 0:
yield x
print(list(even_numbers(10))) # → [0, 2, 4, 6, 8]
Using for‑in
for num in even_numbers(10):
print(num)
Output:
0 2 4 6 8
Using next()
gen = even_numbers(10)
for _ in range(6):
try:
print(next(gen))
except StopIteration:
print("End of generator")
Output:
0 2 4 6 8 End of generator
Generators Are One‑Time Use
Once a generator has been fully iterated, it is exhausted. Re‑iterating yields nothing unless the generator function is called again.
gen = even_numbers(10)
for num in gen:
print(num)
print(list(gen)) # → []
Yield in Action: Fibonacci Series
def fibonacci_series(limit):
a, b = 0, 1
count = 0
while count < limit:
yield a
a, b = b, a + b
count += 1
fib = fibonacci_series(7)
for num in fib:
print(num)
Output:
0 1 1 2 3 5 8
Calling a Function that Yields
Below we square numbers using a helper and a generator that yields each result.
def square(n):
return n * n
def square_range(n):
for i in range(n):
yield square(i)
for value in square_range(10):
print(value)
Output:
0 1 4 9 16 25 36 49 64 81
When to Use Yield Over Return
- Processing large or streaming data where loading all items at once is impractical.
- Generating potentially infinite sequences (e.g., lazy file readers).
- Improving memory footprint and startup time for sizeable datasets.
- When you need to pause and resume computation, not just return a final value.
Yield vs. Return – Quick Reference
| Yield | Return |
|---|---|
| Returns a generator; execution resumes on iteration. | Terminates function; returns a single value immediately. |
Pauses at each yield, conserving memory. | Allocates memory for the returned value. |
| Ideal for large or infinite sequences. | Suitable for small, discrete results. |
| Execution time is faster for large datasets. | May incur overhead when handling huge data. |
Key Takeaways
- Yield produces a generator object, not a value.
- Generators deliver values lazily, keeping memory usage minimal.
- Read values via
for‑in,list(), ornext(). - Once exhausted, generators must be recreated for reuse.
- Yield outperforms return for large or streaming data.
Python
- Master Python Functions: Syntax, Types, and Practical Examples
- Mastering Python Function Arguments: Positional, Keyword, and Default Parameters
- Python Generators: Efficient Iteration and Advanced Use Cases
- Python Closures Explained: How Nested Functions Capture Variables
- Mastering Python’s strip() Method: Comprehensive Guide & Practical Examples
- Understanding Python's Main Function: A Practical Guide to def main()
- Mastering Python Functions: Definition, Calling, Indentation, Arguments & Return Values
- Mastering Python’s enumerate(): Loop with Indices for Lists, Tuples, Strings, and Dictionaries
- Python time.sleep(): How to Add Delays in Your Code (Example)
- Python Calendar Module: Expert Guide with Code Examples