Difference between revisions of "Generator"

From CS 61A Wiki
Jump to: navigation, search
[checked revision][checked revision]
(Major content addition)
m (Minor addition of explanations)
 
(One intermediate revision by one user not shown)
Line 11: Line 11:
 
         curr *= 2
 
         curr *= 2
 
</syntaxhighlight>  
 
</syntaxhighlight>  
Now, each time that <code>__next__</code> is invoked on the generator (e.g. through the <code>next</code> function or a <code>for</code> loop), code from the function will be executed up through the yield statement. The expression next to the yield statement will then be yielded as the result of invoking <code>__next__</code> on the generator object.
+
Now, each time that <code>__next__</code> is invoked on the generator (e.g. through the <code>next</code> function or a <code>for</code> loop), code from the function will be executed up through the yield statement. The expression next to the yield statement will then be yielded as the result of invoking <code>__next__</code> on the generator object. Then, the next time <code>__next__</code> is invoked, the execution starts from where it has previously left off and continues until it hits yield again. <ref>http://www.jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/</ref>
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
>>> a = double_iter()
 
>>> a = double_iter()
Line 23: Line 23:
 
4
 
4
 
</syntaxhighlight>  
 
</syntaxhighlight>  
 +
To stop the generator from producing another value, one can either raise a <code>StopIteration</code> exception or return None. Note that returning None also happens by default when one reaches the end of the body.
  
 
== Generator expression ==
 
== Generator expression ==
A generator can also be created directly via a ''generator expression'', which uses the same syntax as a list comprehension but evaluates to a generator object instead of a list.
+
A generator can also be created directly via a ''[[generator expression]]'', which uses the same syntax as a list comprehension but evaluates to a generator object instead of a list.
 
<syntaxhighlight lang="python">
 
<syntaxhighlight lang="python">
 
>>> a = (i*2 for i in range(5))
 
>>> a = (i*2 for i in range(5))
Line 40: Line 41:
 
8
 
8
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
==External Links==
 +
* [https://docs.python.org/3/reference/expressions.html#generator-expressions Python documentation on generator expressions]
 +
* [https://docs.python.org/3/reference/expressions.html#yield-expressions Python documentation on <code>yield</code>]
 +
 +
==References==
 +
<references>

Latest revision as of 10:07, 29 July 2014

In Python, a generator is a built-in object that satisfies the iterator interface. Specialized syntax such as generator expressions and the yield keyword makes generator objects a concise way of creating an iterator. A generator is lazy, producing an item only when asked for it, so it is memory efficient. As such, generators can also represent infinite sequences.

yield statement

When a function body contains a yield statement, the function will then output a generator object when called.

def double_iter():
    curr = 1
    while True:
        yield curr
        curr *= 2

Now, each time that __next__ is invoked on the generator (e.g. through the next function or a for loop), code from the function will be executed up through the yield statement. The expression next to the yield statement will then be yielded as the result of invoking __next__ on the generator object. Then, the next time __next__ is invoked, the execution starts from where it has previously left off and continues until it hits yield again. [1]

>>> a = double_iter()
>>> a
<generator object double_iter at 0x10f14e678>
>>> next(a)
1
>>> next(a)
2
>>> next(a)
4

To stop the generator from producing another value, one can either raise a StopIteration exception or return None. Note that returning None also happens by default when one reaches the end of the body.

Generator expression

A generator can also be created directly via a generator expression, which uses the same syntax as a list comprehension but evaluates to a generator object instead of a list.

>>> a = (i*2 for i in range(5))
>>> a
<generator object <genexpr> at 0x109d90558>
>>> next(a)
0
>>> next(a)
2
>>> for elem in a:
...     print(elem)
4
6
8

External Links

References

  1. http://www.jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/