Generator Examples (yield)
This page was last reviewed on Apr 14, 2023.
Dot Net Perls
Generators. Python provides ways to make looping easier. With a generator, we specify what elements are looped over. Generators are reusable—they make code simpler.
There are two ways to specify a generator. With the yield-keyword, we encapsulate a looping mechanism into a method. With an expression, we use the for-keyword to specify simpler generators.
Yield. The term yield has a meaning similar to "produce": it dispatches specified elements. Unlike return, control returns again to the method.
Here The odds() method yields odd elements in an iterable. It has a yield statement in it.
Info The yield statement can return an expression, not just a variable. Try changing "yield a" to "yield a + 1".
Also The yield pattern here is the more powerful form. It can filter and transform elements.
def odds(arg): # Yield odd elements in the iterable. for a in arg: if a % 2 != 0: yield a # An input list. items = [100, 101, 102, 103, 104, 105] # Display all odd items. for item in odds(items): print(item) # Print copied list. copy = list(odds(items)) print(copy)
101 103 105 [101, 103, 105]
Expression. Sometimes in Python programs we see generator expressions. These return an iterator. Here we multiply each element in the list by 2 with a generator expression.
String List
Info The expression "A" for "B" in "C" uses the generator expression syntax form.
Part 1 The first part, "A," is the result expression. We can use any expression we want.
Part 2 The second, "B," is the element we are acting upon within the collection "C."
# Example integers. items = [100, 10, 1] # Use generator expression. multiplied = list(x * 2 for x in items) print(multiplied)
[200, 20, 2]
Performance. In Python, list comprehensions are similar to generators. Are generators faster? In the Python documentation, we learn that list comprehensions tend to use more memory.
Version 1 This version of the code uses a generator expression. We create a list on each iteration.
Version 2 Here we use a list comprehension. The syntax is similar to the version with a generator in it.
Result I found that a list comprehension was faster in both implementations I tried, Python and PyPy.
So Often a list comprehension is faster despite the increased memory usage that may occur (according to the Python documentation).
import time data = [1, 2, 3, 4, 5, 6, 7, 8, 9] print(time.time()) # Version 1: generator. i = 0 while i < 1000000: double = list(x * 2 for x in data) i += 1 print(time.time()) # Version 2: list comprehension. i = 0 while i < 1000000: double = [x * 2 for x in data] i += 1 print(time.time())
1404138028.766 1404138031.806 Generator: 3.04 s [Python 3.3] 1404138033.569 List comprehension: 1.76 s 1404137810.806 1404137811.086 Generator: 0.28 s [PyPy 2.3.1] 1404137811.287 List comprehension: 0.20 s
Discussion. In declarative programming (like generators), we specify our requirement with a declaration. Python then does the low-level work to fulfill our request.
And Imperative programming is where you specify individual statements on lines. It often involves traditional loops.
Info In lists, we use list comprehensions (which require square brackets). And with map(), we also create iterators in a declarative way.
A review. Generators simplify iteration. With them, we create looping abstractions. We then can reuse looping methods throughout programs—this leads to less code and higher-quality logic.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Apr 14, 2023 (edit).
© 2007-2024 Sam Allen.