Definition: A generator is like a normal function that generates a range of values using the yield keyword. It returns one object at a time. It internally uses an iterator. To access the next element next() function is used, or we can use it for a loop. If we try to access the value outside the range, it raises a StopIteration error.
We will see some example to understand better
Ex: generator function for range of values
def range_fun(n):x = 0
while x < n:
yield x
x += 1
y = range_fun (3)
#call using for loop
print('Generate values using next() method')
for i in range_fun(3):
print(i)
#call generator using next method
print('Generate values using for loop method')
print(next(y))
print(next(y))
print(next(y))
print(next(y))#Stop Iteration exception will be raised
Ex: Generator function for Fibonacci series
def fib_fun(n):x, y = 0, 1
while x < n:
yield x
x, y = y, x + y
z = fib_fun(6) #generator object
print('Generate values using next() method')
print(next(z))
print(next(z))
print(next(z))
print(next(z))
print(next(z))
print(next(z))
print('Generate values using for loop method')
for i in fib_fun(6):
print(i)
Ex: Generator function for creating range of values given start and end values.
def my_range(start, end):current = start
while current < end:
yield current
current +=1
print('Generate values using next() method')
nums = my_range(1,5)
print(next(nums))
print(next(nums))
print(next(nums))
print(next(nums))
print('Generate values using for loop method')
for num in my_range(1,5):
print(num)
Ex: Generator to multiply each number(less than a number) by a number
def gen_mulby_num(max,num):n = 0
while n < max:
yield n * num
n += 1
for i in gen_mulby_num(5,3):
print(i)
Ex: Generator to find cube for range of values
def gen_mulby_num(max,num):n = 0
while n < max:
yield n * num
n += 1
for i in gen_mulby_num(5,3):
print(i)
Ex: multiple generators: find the square of even numbers generated from a number
Generator 1: generate even values from a given number
Generator 2: generate square numbers from generator1 values
def gen_even(m):n = 0
while n < m:
if n % 2 == 0:
yield n
n += 2
def gen_square(nums):
for num in nums:
yield 2 * num
for n in gen_square(gen_even(15)):
print(n)
Ex: Multiple generators: create fibnacci series and add value 10 each number.
Generator1: generates fibonacci series from a given number
Generator2: add each number by 10 from generator1
def gen_fib(n):x, y = 0, 1
while x < n:
yield x
x, y = y, x + y
def gen_add_10(nums):
for num in nums:
yield 10 + num
for n in gen_add_10(gen_fib(5)):
print(n)
Generator comprehensions:
Generator comprehensions are similar to list comprehensions where the list uses square brackets; this uses normal parenthesis.
Ex:
nums = (i for i in range(10))print(type(nums))
print(list(nums))
Difference between Generator and normal function:
- A generator provides values using yield keyword where normal function uses the return keyword
- Generator starts from where it stopped when called next time. The normal function executes all statements every time.
- Generator saves memory as it returns one value at a time. So we can use it to generate infinite values.
Conclusion:
Generator is very helpful when we are handling huge/large data. At a given time, it holds only one single piece of data rather than whole data. Generators concept is considered an advanced concept in python.