Any function containing a yield statement becomes a generator function: calling it doesn't run the body immediately, it returns a generator object, an iterator that only executes code up to the next yield each time you call next() on it, or iterate over it in a for loop. Between yields, the function's entire local state — variables, the current line, loop position — is paused and preserved, then resumed exactly where it left off. This makes generators ideal for producing large or infinite sequences without holding every value in memory at once.
1Understanding Generators (yield)
Any function containing a yield statement becomes a generator function: calling it doesn't run the body immediately, it returns a generator object, an iterator that only executes code up to the next yield each time you call next() on it, or iterate over it in a for loop. Between yields, the function's entire local state — variables, the current line, loop position — is paused and preserved, then resumed exactly where it left off. This makes generators ideal for producing large or infinite sequences without holding every value in memory at once.
Use a generator instead of building and returning a full list whenever you're processing a large or unbounded sequence, especially if the caller only needs to iterate over it once — it can dramatically reduce memory usage.
def countdown(n):
while n > 0:
yield n
n -= 1
for number in countdown(3):
print(number)2Practical Example
Here is a real-world application of Generators (yield) showing how it is used in production Python code.
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
fib = fibonacci()
print([next(fib) for _ in range(6)])3Best Practices
Follow these guidelines when working with Generators (yield):
1. Use a generator function (or a generator expression) instead of building an entire list in memory when the caller only iterates over the result once
2. Use yield to produce infinite or very large sequences lazily, since a generator computes values on demand rather than all at once upfront
3. Remember a generator is exhausted after one full iteration — convert it to a list explicitly if you need to iterate over the same values more than once
Tip: Use a generator instead of building and returning a full list whenever you're processing a large or unbounded sequence, especially if the caller only needs to iterate over it once — it can dramatically reduce memory usage.
def countdown(n):
while n > 0:
yield n
n -= 1
for number in countdown(3):
print(number)