1. Home
  2. Docs
  3. Python 201
  4. Generator Functions

Generator Functions

 
In this lesson you learn about, generator functions in Python.

What is a generator ?

A generator is special type of iterator,

you can only iterate though them only once.

Generator functions are memory efficient.

Normal functions use ‘return’ keyword to return a value.

Where as generator functions use ‘yield’ keyword to return value.

Generators generate elements on the go, instead of creating all elements at once.

Before we move further, Let’s look at an example.

You might have already used range() built-in function.

Which is a generator function.
 

range() is a generator

  

range([start],end,[step])


type(range(10))

output:

range

  

We can check how range() is memory efficient, by creating different

size range object and checking the size of object.

To check size of the object in memory, we will make use of

getsizeof() function of sys module.

 
Ex 1:
 
Create a range object of size 10.
  

from sys import getsizeof

r1 = range(10)


getsizeof(r1)

ouput:

48

  
Ex 2:
 
Create a range object of size 100.
  

r2 = range(100)

getsizeof(r2)

output:

48

 
Ex 3:
  
Create a range object of bigger size, lots of zeros.
  

r3 = range(100000000000000)


getsizeof(r3)

output:

48

 
Irrespective of number of objects range() generators,

The size of the object remains the same, because its

generating one item at a time.
 

Creating a generator function

 
You can create your generator function, using yield keyword,

instead of return.
 

syntax:
  

def function_name([args]):

    yield

  

So what is generator function ?

 
A function with yield keyword, is a generator function.
 
Let’s create some generators.
 
Ex 1:
 
difference between a normal and generator function
 
simple function to return a value
  

def simple_function():

    return 10

f1 = simple_function()

f1

output:

10

  
simple_function returns a value, 10
 
simple generator function to return generator object.
  

def simple_generator():

    yield 10

g1 = simple_generator()

g1

output:

<generator object simple_generator at 0x000001C6FDE5DBF8>

  
simple_generator() returns a generator object.
 

But how to access the value of generator?

 
You can use next() to access values.

or by iterating through generator object using for-loop.
  

next(g1)

output:

10

  

You can use next() function to get the values, until the generator exhausts.

Once generator reaches end, it throws StopIteration exception.

In above example, simple_generator() yields only one value,

and we have accessed it by next(g1).

If next(g1) is called again, you will get StopIteration.

  

next(g1)


output:

---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-5-9abcc56105c0> in <module>()
----> 1 next(g1)

StopIteration:


  

Don’t use return and yield together in a function.

Ex 2:
 
Generator function to generate cube of numbers.
  

def gen_cubes(n):
    
    for num in range(n):
        
        yield num**3


gen_cubes(10)

output:

<generator object gen_cubes at 0x000001C6FDE5D620>

  
Generator object is created, now lets access the items

using for-loop.
  


for cube in gen_cubes(10):
    
    print(cube, end=" ")


output:

0 1 8 27 64 125 216 343 512 729 

  

Ex 3:

Generating Fibonacci numbers.

A Fibonacci series is a sequence of number, where a

number is sum of its two preceding numbers

1,1,2,3,5,8,13…… is a simple Fibonacci series.

  

def gen_fib(n):

    a = 1
    
    b = 1
    
    for i in range(n):
        
        yield a
        
        a,b = b,a+b 

for fib in gen_fib(10):
    
    print(fib, end=' ')

output:

1 1 2 3 5 8 13 21 34 55 

  

yield multiple values from a function

 
You can have multiple yield statements in a function, like return.

In the below function func(), yields ’10, 20, 30 and some string’

when it is called.

  

def func():
    
    print('In func, yielding 10')
    
    yield 10
    
    print('In func, yielding 20')
    
    yield 20
    
    print('In func, yielding 30')
    
    yield 30
    
    print("In func, yielding 'some string' ")
    
    yield 'some string'
    
    

for yld in func():
    
    print('for loop : yld = ',yld)



output:


In func, yielding 10

for loop : yld =  10

In func, yielding 20

for loop : yld =  20

In func, yielding 30

for loop : yld =  30

In func, yielding 'some string' 

for loop : yld =  some string