This is similar to the benefits provided by iterators, but the generator makes building iterators easy.
Furthermore, we do not need to wait until all the elements have been generated before we start to use them. The performance improvement from the use of generators is the result of the lazy (on demand) generation of values, which translates to lower memory usage. The uniform way in which all of these are handled adds greatly to the simplification of code. Keep in mind that generators are a special type of iterator, and that containers like list and set are also iterables. This also means that we can use the same syntax we have been using for list comprehensions to build generators. If only list comprehensions were available, and we needed to lazily build a set of items to be processed, we will have to write a generator function. Notice how a list comprehension looks essentially like a generator expression passed to a list constructor.īy allowing generator expressions, we don't have to write a generator function if we do not need the list. Alternately, we can think of list comprehensions as generator expressions wrapped in a list constructor.ġ # list comprehension 2 doubles = 3 4 # same as the list comprehension above 5 doubles = list( 2 * n for n in range( 50)) In fact, we can turn a list comprehension into a generator expression by replacing the square brackets ("") with parentheses. Generator expressions provide an additional shortcut to build generators out of expressions similar to that of list comprehensions. The built-ins will always be much faster.
#GENERATOR CODE#
Note: the above code is perfectly acceptable for expository purposes, but remember that in Python 2 firstn() is equivalent to the built-in xrange() function, and in Python 3 range() is an immutable sequence type. It is very similar to the implementation that built a list in memory, but has the memory usage characteristic of the iterator implementation. Note that the expression of the number generation logic is clear and natural.
1 # a generator that yields items instead of returning a list 2 def firstn( n): 3 num = 0 4 while num < n: 5 yield num 6 num += 1 7 8 sum_of_first_n = sum( firstn( 1000000))