I'm a Systems Reliability and DevOps engineer for Netdata Inc. When not working, I enjoy studying linguistics and history, playing video games, and cooking all kinds of international cuisine.
A generator is a compact way of expressing a particular sequence of items as a function.
The most important aspects are:
Generators are also inherently iterators. Anything that expects an iterator can be passed a generator instead. The simplest example is a for...in loop, but there are many others (for example the map() builtin function)
Each item in the sequence is generated (hence the name) as it's requested.
Because values are generated on demand, you can save time if you need to search a sequence of items that are computationally expensive to compute by avoiding the need to compute the whole list.
Because values are generated on demand, it's insanely memory efficient (a generator that produces a million items only needs to take up as much space as the code itself and any variables the generator uses to store state).
It doesn't have to terminate. Unlike looping over a list, looping over a generator doesn't have to stop at some point, it can just go on forever (this is also really useful for some applications).
Generators are one-use only. Once you've used it, you have to make a new one to start over.
The important part of a generator is the yield statement. Each time whatever is iterating over the generator asks for the next item in the sequence, the generator function is run up until the next yield statement is encountered, then the value provided to that statement is returned s the next item in the sequence. The key point to understand here is that after this, the generator function is 'paused' until the next time the generator gets asked for a new item. When an item is asked for again, the generator function resumes execution from exactly where it was previously, retaining the values that any variables local to the generator function had previously.
Further explanation will require some code, so here's an example:
deffibonacci():last=0# Previous term
current=1# Current term
tmp=0# Temporary storage
whiletrue:yieldcurrenttmp=lastlast=currentcurrent+=tmp
This is a trivial generator function that will spit out the terms of the Fibonacci sequence. There's no termination condition, so if you were to loop over it, it the loop would just keep going forever.
Assume we start looping over this generator like so (don't do this unless you want to have to manually kill the Python interpreter, it will loop forever):
forxinfibonacci():print(x)
The overall execution flow will look like this:
The generator function will start up by initializing the local variables at the top of the function body.
We'll move into the infinite loop.
We hit the yield statement, which returns the value of current as the next item.
The generator pauses, and the body of the for loop runs with x equal to to the value of current.
The for loop asks for the next item from the generator, restarting the generator function.
The generator function updates it's internal state, computing the next value to return.
We reach the end of the body of the infinite loop in the generator and return to step 3.
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
A generator is a compact way of expressing a particular sequence of items as a function.
The most important aspects are:
for...in
loop, but there are many others (for example themap()
builtin function)The important part of a generator is the
yield
statement. Each time whatever is iterating over the generator asks for the next item in the sequence, the generator function is run up until the nextyield
statement is encountered, then the value provided to that statement is returned s the next item in the sequence. The key point to understand here is that after this, the generator function is 'paused' until the next time the generator gets asked for a new item. When an item is asked for again, the generator function resumes execution from exactly where it was previously, retaining the values that any variables local to the generator function had previously.Further explanation will require some code, so here's an example:
This is a trivial generator function that will spit out the terms of the Fibonacci sequence. There's no termination condition, so if you were to loop over it, it the loop would just keep going forever.
Assume we start looping over this generator like so (don't do this unless you want to have to manually kill the Python interpreter, it will loop forever):
The overall execution flow will look like this:
current
as the next item.x
equal to to the value ofcurrent
.