Generators in Python: Is there a need for them?

Photo by Sigmund on Unsplash

Generators in Python: Is there a need for them?

·

3 min read

I was working with a bunch of Python newbies and a majority of them said they had never heard of, used, or needed Python generators. So, it got me thinking about how many people may or may not be aware of generators, their uses, and their importance. Hence, the need for this article.

What is a Python Generator?

A python generator is basically a python function with a yield rather than a return keyword. They are a simple way of creating python iterators (A class-based object that can be looped through to return data, one value at a time).

Once a function contains at least one yield statement, irrespective of whether or not there is a return statement, it is referred to as a generator. More simply put, a function that generates and yields data, one value at a time.

Here is a typical generator that yields one odd number at a time.

def odd_number_gen(max):
    for number in range(1, max+1):
        if number%2 != 0:
            yield number

print(odd_number_gen(11))

I do Imagine that you are expecting the function above to print out odd numbers between 1 and 12 (max+1), but "unfortunately", that is not the case. The above print statement will return an object recognition, like below.

<generator object odd_number_gen at 0x7fad3a3103c0>

This simply says that what you have as the odd number generator function, is in fact a generator, and not just any ordinary function. How then do we print out the values of a generator? Generator values can be printed out in the following ways:

1. By Using For Loops

for value in odd_number_gen(11):
  print(value)

This would return the output below:

1
3
5
7
9
11

2. By using the next() inbuilt function

This is called every time you need to yield new data from the generator. In this method, If the next() keyword is called after the end of the iteration, in this case when we are out of data to yield, The generator automatically raises a ```StopIteration``` exception.item = odd_number_gen(11) print(next(item)) # 1 print(next(item)) # 3 print(next(item)) # 5 print(next(item)) # 7 print(next(item)) # 9 print(next(item)) # 11 print(next(item)) # StopIteration exception is raised because there is no more value to yield.

### Why would I ever need a generator?

Here are some of the reasons why using a Python generator would be a better option. 1. Memory Efficiency: Because a generator only produces items or data when asked for it, it is more memory efficient. It does not allocate memory to all values of the data at a go. It conserves memory by only providing what is required at every time given. 2. Ease of implementation: In comparison to the more complicated Iterator class, the generator is much easier to understand and use. 3. Effective for a limitless amount of data: As a result of its memory efficiency, generators are much advised for outputting or interacting with a large or infinite amount of data. They ensure that memory slots or storage is not "wasted" on storing this data. It is best to get only what you need when you need it. There are Python generator expressions, kind of like list comprehensions but with parenthesis "()" and without the memory allocation. They are quick ways to create generators, without writing full functions. Using the same odd number code above, here is a generator expression.

odd_number_gen = (number for number in range(1, 11) if number%2 !=0)

print(odd_number_gen) # gives <generator object at 0x7fae6db103c0>

Just as we've seen above, the generator expression will also print a generator object value. The data in the generator is yielded in the methods already provided. So, when next you are looping through or processing a large amount of data, maybe consider using a generator. If you enjoyed reading this and want to buy me coffee, hit [here.](https://www.buymeacoffee.com/resa) Thank You!