DEV Community

Cover image for Learn Generators in Python with (Examples)
Adarsh Rawat
Adarsh Rawat

Posted on

Learn Generators in Python with (Examples)

In this Article we will going to look following topics

  • Understanding Generators in Python,with Examples
  • Also how to construct our own Generator function
  • Advantages of using Generator function instead of regular function in some cases

Generators :-

  • Generator are the special function which returns an traversal object which used to iterate over a collection of values, it is also used to create iterators.

  • It is can also be expressed in a way which is simiar to list compreshension

  • Just like iterator next() method we can also iterate over generator using generator.next() to iterate over the generator.

Creating a Geneartor :-

  • It is simple to create a Generator function if you have worked with regular function.

  • In Generator function instead of using return statement we use yield statement.

  • A function with yield keyword in it is called a Generator function

  • generator throws StopIteration Exception when next() method called on the last element in the genearator,

  • We have to explicitly handle StopIteration Exception when
    using next() method with generator

let's use take an example to understand the above points :-

Example :-

# Normal function
def func():
    letters = ['a', 'b', 'c', 'd', 'e']
    for c in letters:
        return c

# Generator function
def generator_func():
    letters = ['a', 'b', 'c', 'd', 'e']
    for c in letters:
        yield c

print("Normal function :-")
print(func())

print("\nGenerator function :-")
print(generator_func())

print("\nIterating over generator using next() method")
gen = generator_func()
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))

Output :-

Normal function :-
a

Generator function :-
<generator object generator_func at 0x00000180318F9A10>

Iterating over generator using next() method
a
b
c
d
e
Traceback (most recent call last):
  File "C:\Users\adars\Desktop\test.py", line 26, in <module>
    print(next(gen))
StopIteration   
Enter fullscreen mode Exit fullscreen mode

Now , you can se a normal function return the value which we have return but , Generator function return generator object (traversal object)

we can iterate over the generator object, let's see how?

Example :-

for i in generator_func():
    print(i)

Output :-
a
b
c
d
e
Enter fullscreen mode Exit fullscreen mode

we iterated over the generator object in the above code,

Now you're probably thinking what is the difference between :-

  • function with return
  • function with yield

function with return statement

  • when the return statement called , the function terminates it execution and return the value, removing the function from the call stack.

function with yield statement

  • yield controls the flow of Genearator
  • yield pauses the function state and yielded value to the caller
  • yield resume the function execution on yield statement successfully
  • there can be multiple yield statement per Generator function

Generator with multiple yield statements

Example :-

def generator_func2():
    numbers = [1, 2, '3', '4', 5, 6, '7', 8, 9, '10']
    for num in numbers:
        if type(num) == int:
            yield f"{num} is an integer form"
        elif type(num) == str:
            yield f"{num} is an string form"



for i in generator_func2():
    print(i)


Output :-
1 is an integer form
2 is an integer form
3 is an string form
4 is an string form
5 is an integer form
6 is an integer form
7 is an string form
8 is an integer form
9 is an integer form
10 is an string form
Enter fullscreen mode Exit fullscreen mode

In the above example we created a Generator function which uses
multiple yield statments

Creating Generator in one line

  • Just like list comprehension , we can create Generators in single line
  • Instead of [ ] brackets ,we use ( ) to create a generator function

Example :-

numbers_generator = (i for i in range(10))
print(type(numbers_generator))

for num in numbers_generator:
    print(num)

Output :-
0
1
2
3
4
5
6
7
8
9
Enter fullscreen mode Exit fullscreen mode

In the above example we have created a Generator function which belong to generator class, in a way similar to list comprehension

let's take some more example of generators function

If your fimilar with range() function in python , we will going to implement our own range() function with the help of generators.

Example :-

def range(start = 0,stop = 0,stepby = 1):
    yield start
    while(start < stop):
        yield start+stepby
        start += stepby

print("range() function implementation :-")
print(type(range(0,10)))


for i in range(0,10):
    print(i)

print("\n---------\n")

for i in range(0,10,2):
    print(i)

Output :-
range() function implementation :-
<class 'generator'>
0
1
2
3
4
5
6
7
8
9
10

---------

0
2
4
6
8
10
Enter fullscreen mode Exit fullscreen mode

We have created a simple implementation of range() function
using generators

*We will going to write two implementation of *fibonacci sequence using generators

Example

def fibo_seq_generator(n):

    # Initialize first two Fibonacci Numbers 
    a, b = 0, 1

    # One by one yield next Fibonacci Number
    while a < n:
        yield a
        a, b = b, a + b

print("Fibonacci sequence using generator :- ")
for i in fibo_seq_generator(20):
    print(i)

Output :- 
Fibonacci sequence using generator :-
0
1
1
2
3
5
8
13
Enter fullscreen mode Exit fullscreen mode

Now that we have covered many examples of generators and
learned how to create generators, now we're going to see
the advantages of generator :-

Advantages of Genearators

  • It is Easy to Implement a generators relatively compared to
    an iterator , which requires you to implement iter_() and
    next() function.

  • Genearators are memory efficient when working with large
    sequence of numbers because yield statement give value to
    the caller function whenever yield line gets executed ,
    So it doesn't have to store the entire sequence in the memory,
    whereas in case of normal function ,it stores the sequence
    somewhere in memory(in call stack) before returning the result.

  • With Generators we can generate infinite sequence of numbers without needing to worry about computer memory usage.

  • Generators used in Data Pipeline which provides the facility to process large datasets or stream of data without using extra computer memory.

with this we have successfully completed
Generators in Python with (Examples) Article
hope you all have understand the topics
covered in this Article.

:-)

Top comments (0)