python


Python Generators


In this tutorial, we will learn about generators in python,how they are different with iterators and normal functions and use of generators.

Generators in Python

As we know to build an iterator we have to use __iter__() and __next__() method.And we also use StopIteration to prevent the function to infinity.
But these methods are bit lengthy.Generator comes here to prevent this and helps to rescue from these situations.

Generators can be defined as a simple way of creating iterators.
Basically, a generator is a function that returns an object(iterator) which we can iterate over.

How to create Generators in python?

It is very easy to create generators in python.It is similar to defining a normal function but with a yield statement instead of return statement.
The difference between the yield and return statement is that return statement terminates the entire function in one time while yield statement to return each element one at a time.After running one time, it pauses the function and saves all its states and later continues for next calls.

Main points about Generator function
Python generators with loops

In ths section we will learn about how generators can be used with loops.
The generator functions are implemented within a lopp under suitable terminating condition.

Example:
def rev_list(a=[]):
    length = len(a)
    for i in range(length - 1, -1, -1):
        yield a[i]

# For loop to reverse the string
for word in rev_list(["hello","welcome","to","my","program"]):
    print(word)
    
Output:
program
my
to
welcome
hello

In the above program we used generator that reverses a list and here we used range() function to get the index of the reverse order of the list.

Python Generator Expression

Generators can be easily created by using generator expressions.It makes building generator very easy.
Generator expressions create anonymous generator functions like lambda functions which are used to create anonymous functions.

Syntax:

The syntax for generator expression is similar to that of a list comprehension in Python. But the square brackets are replaced with round parentheses.

Example:
# Initialize the list
my_list = [1,5,25,100]

# multiply each term by 2 using list comprehension

list_1 = [var*2 for var in my_list]

# same thing can be done using a generator expression
# generator expressions are surrounded by parenthesis ()

generator_1 = (var*2 for var in my_list)

print(list_1)
print(generator_1)

print(next(generator_1))
print(next(generator_1))
print(next(generator_1))
print(next(generator_1))
Output:
[2, 6, 12, 20]
 at 0x7f6a440c7510>
2
6
12
20

As you can see the above code will return a generator object which produces items only on demand.
To produce the result we have to pass the generator in next statement..

Use of Python Generators
  1. Easy Implementation
  2. Generators can be implemented in very simple and concise way as compared to the iterator.
    Let's take an example, we will create a simple program by using iterator as well as generator.

    Iterator example:
    class Multi:
        def __init__(self, mix=0):
            self.n = 0
            self.mix = mix
    
        def __iter__(self):
            return self
    
        def __next__(self):
            if self.n < self.min:
                raise StopIteration
    
            result = 2 * self.n
            self.n += 1
            return result
    
    Generator example:
    def MultiGen(min=0):
        n = 0
        while n < min:
            yield 2 * n
            n += 1
    
  3. Memory Efficient
  4. A normal function to return a sequence will create the entire sequence in memory before returning the result.
    Generator implementation of such sequences is memory friendly and is preferred since it only produces one item at a time.