yield keyword is used to create generator functions. Unlike return, which exits the function, yield returns one value at a time and pauses the function. When called again, the function resumes execution from where it was paused.
def numbers():
yield 1
yield 2
yield 3
for num in numbers():
print(num)
Output
1 2 3
Explanation: function numbers() returns one value at a time using yield. Each time the for loop requests the next value, execution resumes from the previous yield statement until all values are produced.
Why Do We Need yield Keyword?
yield keyword allows a function to generate values one at a time instead of returning them all at once. Some benefits of using yield include:
- Saves memory by generating values one at a time.
- Pauses and resumes function execution when the next value is requested.
- Supports large or infinite sequences without storing all values in memory.
- Works well with loops for iterating over generated values.
Syntax
def generator_function():
yield value
- Parameter: value - The value returned by the generator each time the yield statement is executed.
- Returns: Returns a generator object. Each call to next() (or iteration using a for loop) retrieves the next yielded value.
Examples
Example 1: Here, we generate numbers from 0 to 4 using the yield keyword.
def fun(m):
for i in range(m):
yield i
for n in fun(5):
print(n)
Output
0 1 2 3 4
Explanation: fun(m) generates numbers from 0 to m-1 using yield. Calling fun(5) returns a generator, which for loop iterates over, yielding values one by one until completion.
Example 2: Here, we use next() to retrieve values from a generator one by one.
def my_generator():
yield "Hello world!!"
yield "Python"
g = my_generator()
print(type(g))
print(next(g))
print(next(g))
Output
<class 'generator'> Hello world!! Python
Explanation: my_generator() is a generator that yields "Hello world!!" and "Python", returning a generator object without immediate execution, which is stored in gen.
Example 3: Here, we generate an infinite sequence of numbers and print the first 10 values.
def infinite_sequence():
n = 0
while True:
yield n
n += 1
g = infinite_sequence()
for _ in range(10):
print(next(g), end=" ")
Output
0 1 2 3 4 5 6 7 8 9
Explanation: infinite_sequence() is an infinite generator that starts at 0, yielding increasing numbers. The for loop calls next(gen) 10 times, printing numbers from 0 to 9.
Example 4: Here, we are extracting the even number from the list.
def fun(a):
for n in a:
if n % 2 == 0:
yield n
a = [1, 4, 5, 6, 7]
print(list(fun(a)))
Output
[4, 6]
Explanation: fun(a) iterates over the list a, yielding only even numbers. It checks each element and if it's even (num % 2 == 0), it yields the value.
Example 5: Here, we find all occurrences of a specific word in a sentence using the yield keyword.
def fun(text, keyword):
w = text.split()
for n in w:
if n == keyword:
yield True
txt = "geeks for geeks"
s = fun(txt, "geeks")
print(sum(s))
Output
2
Explanation: fun(text, keyword) is a generator that splits text into words and checks if each word matches keyword. If a match is found, it yields True.
Advantages
- Memory Efficiency: Since the function doesn’t store the entire result in memory, it is useful for handling large data sets.
- State Retention: Variables inside the generator function retain their state between calls.
- Lazy Evaluation: Values are generated on demand rather than all at once.
Disadvantages
- Complexity: Using yield can make the code harder to understand and maintain, especially for beginners.
- State Management: Keeping track of the generator’s state requires careful handling.
- Limited Use Cases: Generators do not support indexing or random access to elements.