Difference between revisions of "Generator"

From CS 61A Wiki
Jump to: navigation, search
[checked revision][checked revision]
(created)
 
m (Minor addition of explanations)
 
(2 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Start-class}}
+
{{C-class}}
In [[Python]], a '''generator''' is a concise way to create an [[iterator]]. A generator returns a ''generator object''.
+
In [[Python]], a '''generator''' is a built-in object that satisfies the [[iterator]] interface. Specialized syntax such as generator expressions and the <code>yield</code> 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.
  
A generator is created by using the <code>yield</code> statement instead of a <code>return</code> statement in a function.
+
== <code>yield</code> statement ==
 +
When a function body contains a <code>yield</code> statement, the function will then output a generator object when called.
 +
<syntaxhighlight lang="python">
 +
def double_iter():
 +
    curr = 1
 +
    while True:
 +
        yield curr
 +
        curr *= 2
 +
</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. 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">
 +
>>> a = double_iter()
 +
>>> a
 +
<generator object double_iter at 0x10f14e678>
 +
>>> next(a)
 +
1
 +
>>> next(a)
 +
2
 +
>>> next(a)
 +
4
 +
</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.
  
A generator is lazy, producing an item only when asked for it, so it is memory efficient.
+
== 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.
 +
<syntaxhighlight lang="python">
 +
>>> 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
 +
</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/