Functional Python Programming

(Wang) #1

Functions, Iterators, and Generators


A display includes the enclosing literal syntax: [x**2 for x in range(10)]; this
example is a list comprehension, which creates a list object from the enclosed generator
expression. In this section, we're going to focus on the generator expression. We'll
occasionally create a display as part of demonstrating how the generator works.
Displays have the disadvantage of creating (potentially large) collection objects.
A generator expression is lazy and creates objects only as required.


We have to provide two important caveats on generator expressions, as follows:



  • Generators appear to be sequence-like except for a function such as the len()
    function that needs to know the size of the collection.

  • Generators can be used only once. After that, they appear empty.


Here is a generator function that we'll use for some examples:


def pfactorsl(x):
if x % 2 == 0:
yield 2
if x//2 > 1:
yield from pfactorsl(x//2)
return
for i in range(3,int(math.sqrt(x)+.5)+1,2):
if x % i == 0:
yield i
if x//i > 1:
yield from pfactorsl(x//i)
return
yield x


We're locating the prime factors of a number. If the number, x, is even, we'll yield 2
and then recursively yield all factors of x÷2.


For odd numbers, we'll step through odd values greater than or equal to 3, to locate
a candidate factor of the number. When we locate a factor, we'll yield that factor, i,
and then recursively yield all factors of x÷i.


In the event that we can't locate a factor, the number must be prime, so we can
yield that.


We handle 2 as a special case to cut the number of iterations in half. All prime numbers,
except 2, are odd.

Free download pdf