Generators allow you to declare a function that operates like an iterator. This allows you to write a custom function that can be used in a for loop or an other iteration capacity. The key feature of a generator is that it yields a value, rather than using return.
When a generator function is called, it returns an iterator known as a generator. This generator controls the operation of the generator function. When the generator is called, the function proceeds like normal but, when the logic flow reaches the yield statement, processing is suspended while returning the first evaluation.
During the suspension, the local state of the function is retained in memory; it's just like a normal function was paused in completing its processing. When the generator is resumed by calling it again, it continues as if nothing happened, returns the next evaluation...