Functional Python Programming

(Wang) #1
Chapter 4

This isn't as delightfully simple and functional-looking as other algorithms
we've looked at. We can rework this into a pleasant-enough generator function.
The following code uses a while loop as part of tail-recursion optimization:


def group_by_iter( n, iterable ):
row= tuple(next(iterable) for i in range(n))
while row:
yield row
row= tuple(next(iterable) for i in range(n))


We've created a row of the required length from the input iterable. When we get
to the end of the input iterable, the value of tuple(next(iterable) for i in
range(n)) will be a zero-length tuple. This is the base case of a recursion, which
we've written as the terminating condition for a while loop.


Structuring flat sequences—an alternative approach


Let's say we have a simple, flat list and we want to create pairs from this list.
The following is the required data:


flat= ['2', '3', '5', '7', '11', '13', '17', '19', '23', '29',
'31', '37', '41', '43', '47', '53', '59', '61', '67', '71',... ]


We can create pairs using list slices as follows:


zip(flat[0::2], flat[1::2])


The slice flat[0::2] is all of the even positions. The slice flat[1::2] is all of the
odd positions. If we zip these together, we get a two tuple of (0), the value from the
first even position, and (1), the value from the first odd position. If the number of
elements is even, this will produce pairs nicely.


This has the advantage of being quite short. The functions shown in the previous
section are longer ways to solve the same problem.


This approach can be generalized. We can use the *(args) approach to generate
a sequence-of-sequences that must be zipped together. It looks like the following:


zip(*(flat[i::n] for i in range(n)))


This will generate n slices: flat[0::n], flat[1::n], flat[2::n], ..., flat[n-1::n].
This collection of slices becomes the arguments to zip(), which then interleaves values
from each slice.

Free download pdf