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.
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.
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 pages with code examples, which are updated to stay current. Programming is an art, and it can be learned from examples.
Donate to this site to help offset the costs of running the server. Sites like this will cease to exist if there is no financial support for them.
Sam Allen is passionate about computer languages, and he maintains 100% of the material available on this website. He hopes it makes the world a nicer place.
This page was last updated on Apr 14, 2023 (edit).