Fundamentals of Python Programming
Generators in Python
What are Python Generators?
Iterators (which can be traversed like a list or tuple) are created using Python's generator functions, which also produce a traversal object. It is useful to move through each item in the iterator one at a time. Normal functions are specified as generator functions, but the distinction between the two is that in a normal function, the values are returned using the return keyword, whereas in a generator function, the iterator is executed using yield in place of return
Example
A generator function is gen _fun() in the example above. This function returns a value whenever it is invoked and does not utilize the return keyword.
Generator function and normal function are different
1) There is just one function in normal functions, however there are one or more yield functions          in generator functions.
2) The normal function pauses execution when the generator function is called, and the call is then passed to the generator function.
3) Local variables and their current states are retained between calls.
4) On subsequent calls, StopIteration is invoked automatically when the generator function is   ended.
Generators in Python With a Loop
The loop also makes use of the Generator functions.
Example
Output:
The function seq will run ten times, and on the eleventh call using next, seq will display the StopIteration error.
However, when using a for loop, use next.
Output:
It won't display any errors. Exception statements are automatically handled by the for loop.
How Do I Make a Python Generator Function?
There are several approaches to build a generator function in Python.
1. Making use of a yield statement
2.Making use of the Python Generator Expression
Yield Statement
Python's yield keyword allows you to exit a function without erasing a local variable's state. We've already spoken about using yield to build generator functions.
Python Generic Expression
A generator function can be expressed informally as a Generator Expression. A Generator Expression can be easily and quickly implemented in Python.
Since both generator functions and lambda functions are anonymous, they fit the definition's description of a lambda function. However, when it comes to implementation, they differ. List comprehension implements both similarly, with the only difference being that round brackets ('()') are used in place of square brackets ('[]').
List comprehension returns a list of elements, whereas generator expression returns an iterable object. This is the primary and most significant distinction between the two.
Example
Output:
(i for i in range(x) if i % 2 == 0) in this generator expression, the first part is the yield part, and next is the for loop, followed by the if statement.
Use of Generators in Python
1. Ease of Implementation: When compared to iterators, generator functions are simpler to implement. Iterators require the implementation of the iter() and __next__() functions in order to function.
2. Memory Efficient: Generator Functions save a lot of memory when employing generators, making them memory efficient. In contrast to the generator function, which produces one output at a time, a normal function returns a sequence of objects after first creating the sequence in memory.
3. Unlimited Sequence: Everyone is aware that there is no memory that can hold an infinite number of sequences. Generators have a role in this situation. Given that generators can only produce one thing at a time, they can only produce one item at a time, so they can present an infinite stream of data/sequence.
Output:
Conclusion
1) Iterators are created using Python's generator functions, which also provide back an iterator object.
2) A yield statement rather than a return statement is used in the generator function.
3) The generator function allows for the usage of numerous yield statements.
4) While using next to iterate over the generator function, the StopIteration error will appear at the conclusion; however, when using the for loop, there is no error displayed.
5)Generic functions called Generator Expressions are nameless. The only difference between them and a list comprehension is that they utilize round parenthesis rather than square ones.