Python Generators: yield

In this post i will try to explain the basics of python generator. And will be writing another post to cover advance use and some debugging techniques.

In python, generator is part of functional programming. A generator is an object that returns a value on each call of its next() method until it raises StopIteration exception.

It’s introduced in PEP255 and offers really easy way to implement Iterator Protocol.

Basic Syntax:

    def a_generator():
        yield 1

Yes, thats all it takes to write a python generator function. It’s just like a normal python function contains yield statement instead of return. Python will detect the yield statement and tag the function as a generator.

When function’s execution reaches a yield statement, it returns a value with a return statement, but in the case of generator python interpreter will save a stack reference, which will be used to resume the function’s execution when next() method is called next time.

    def a_generator():
        yield 'ready'
        yield 'steady'
        yield 'go'

    gen_obj = a_generator()
    next(gen_obj)    # returns 'ready'
    next(gen_obj)    # returns 'steady'
    next(gen_obj)    # returns 'go'
    next(gen_obj)    # raises StopIteration exception

Generators in python are considered slightly advanced topic because of their nature of execution. But they can come really handy in some scenario and helps to keep your code clean while delivering efficient solution to the problem. For example, if you have a function which generates and returns a list of items. This can be simplified using generators.

Refactoring tip using yield:

    def get_best_items(items, best_item_rank=8):
        best_items_list = []
        for item in items:
            if item.rank >= best_item_rank:
                item_list.append(item)

        return best_items_list   

Above function can be simplified using generator as below:

    def get_best_items(items, best_item_rank=8):
        for item in items:
            if item.rank >= best_item_rank:
                yield item

Python for loop is smart enough to catch StopIteration exception if raised and terminates the loop gracefully.

    for item in get_best_items(items):
        print(item)

So by refactoring the function using yield, best_items_list = [] is not required, thus item_list.append(item) should be gone as well. And finally we got our nice and clean function by removing some not so required code for this purpose.

 
1
Kudos
 
1
Kudos

Now read this

Data mining for associated entities

Data mining–the practice of examining large pre-existing databases in order to generate new information. – by google In one of my not so recent project for an e-commerce platform i developed a workflow. A workflow in which raw data is... Continue →