Python

Python Generators

Generators are just like functions with one difference being that using yield instead of the return statement. Generators are memory-efficient expressions for creating a large list of items. It is used to create an infinite sequence or stream. The main quality of the generator is that it remembers the last state of function each time the next() called it resumes from where it left last time. The generator function returns an iterator.

Let’s create a sample_generator() function:

def sample_generator():
    num = 1
    while num < 11:
        yield num
        num += 1
        
for i in sample_generator():
    print(i, end = " ")
Output:
1 2 3 4 5 6 7 8 9 10 

A return statement completely terminates the function while the yield statement freezes the function saving all the states and later continuing from the last value.

Let’s see one example of string reverse using a Generator:

def reverse_string(sample):
    l = len(sample)
    for i in range(l-1,-1,-1):
        yield sample[i]
    
for ch in reverse_string("adams"):
    print(ch, end = "")
Output:
smada

Yield vs Return

  • Yield is used to create the generators while the return is used to create functions.
  • Yield does not delete the local variable, it only suspends the execution while return stops the execution and deletes the local variable.
  • Yield is used to hold the intermediate results and sends them to the caller while the return is used to send the final result back to the caller

Generator Comprehension Vs List Comprehension

  • List comprehensions are enclosed within [ ] whereas generator expressions are enclosed within ( ).
  • The major differences between list comprehension and generator are that list comprehension produces the entire list while the generator expression produces one item at a time as lazy evaluation.
  • Generator expressions are much more memory efficient than list comprehension.

Let’s execute one example to understand the difference in detail:

import sys

# Create sample list
sample_list = [1, 2, 3, 5, 10, 15]

# create list comprehension
list_comprehension = [x**3 for x in sample_list]

# Create generator expression
test_generator = (x**3 for x in sample_list)

# Print the size of list comprehension and generator
print("Size of List Comprehension:", sys.getsizeof(list_comprehension))
print("Size of Generator:", sys.getsizeof(test_generator))
Output:
Size of List Comprehension: 120
Size of Generator: 112