Aug 11, 2022·

# Starting Note

Before reading this blog, I want to make a clear statement that this blog is written completely based on my understanding about how generators work in python. To move forward, you must be an intermediate in python.

# Iterators

An object that contains countable number of values. The next value can be accessed with the `next(object_name)` parameter

You can know more about iterators here: Iterators by W3 Schools

# Case

Let's say you are working in a company and your company gives you a task to write a program to find a series of numbers. Each number having a difference of 12 from the previous. So the series is like: [12,24,36,48.....]

You have to find the series till a number given by the user and store the results somewhere so that others get those values using a loop.

So, if the user enters 10, the program will return a series like: 12,24,36,........,120

You will be like: Okay that's easy

``````def gen_series():
n = int(input("What's n? "))
a = []
d = 11
for i in range(1, n+1):
a.append(i + d)
d += 11
return a

if __name__ == "__main__":
print(gen_series())
``````

Now, your program works nicely if the user inputs numbers like 12, 23, 89, 74.

If you test this code yourself and you enter a number like 1000000000000000 then what happens? Your code starts to hang, the program doesn't work smoothly. So, this is not the best approach to get a series of numbers.

Let's refactor this code a bit

``````def gen_series():
n = int(input("What's n? "))
a = series(n)
print(a)

def series(n):
a = []
d = 11
for i in range(1, n+1):
a.append(i + d)
d += 11
return a

if __name__ == "__main__":
gen_series()
``````

Now, the program runs the same but our problem is not yet solved. We want to generate a series of numbers with each number having a difference of 12 from the previous and we want our program to generate as much numbers as we want.

Try to run this code:

``````def gen_series():
n = int(input("What's n? "))
a = series(n)
print(a)

def series(n):
d = 11
for i in range(1, n+1):
yield i + d
d += 11

if __name__ == "__main__":
gen_series()
``````

If you run this code and input a number as 20, you will see the output as `<generator object series at 0x0000020B20684350>`. Now, if you run again, and input a big number such as 1000000000000000, you will notice that your program doesn't lag. It works perfectly fine and you get the output.

The `yield` keyword is responsible to make this function a generator.

The `series` function is now a generator function which generates an iterator. If you have read the article of W3 Schools, you will certainly know that we can easily access the values from an iterator using a loop.

So, here's the definition of generators

### Generators

Generators are those kind of functions that return an iterator.

# Back to program

Now to print the values of the series we can use another function

``````def print_series():
a = gen_series()
for i in a:
print(i)
``````

The complete code:

``````def gen_series():
n = int(input("What's n? "))
a = series(n)
print(a)
return a

def print_series():
a = gen_series()
for i in a:
print(i)

def series(n):
d = 11
for i in range(1, n+1):
yield i + d
d += 11

if __name__ == "__main__":
print_series()
``````

# Conclusion

• Generators are functions that return an iterator
• We can turn a normal function to generator by using the `yield` keyword

If you didn't understand then don't forget to criticize me in the comments. That will help me to come up with a better explanation. It is okay to criticize me if I have wasted your time. Also if you have any questions, please ask me in the comments