Functional Python Programming

(Wang) #1

Working with Collections


We can write nested generator functions to build a sequence-of-sequence structure
from flat data. In order to do this, we'll need a single iterator that we can use multiple
times. The expression looks like the following code snippet:





flat_iter=iter(flat)
(tuple(next(flatiter) for i in range(5)) for row in
range(len(flat)//5))
<generator object at 0x101cead70>
list(
)
[('2', '3', '5', '7', '11'), ('13', '17', '19', '23', '29'),
('31', '37', '41', '43', '47'), ('53', '59', '61', '67', '71'),
('73', '79', '83', '89', '97'), ('101', '103', '107', '109',
'113'), ('127', '131', '137', '139', '149'), ('151', '157', '163',
'167', '173'), ('179', '181', '191', '193', '197'), ('199', '211',
'223', '227', '229')]





First, we created an iterator that exists outside either of the two loops that we'll use to
create our sequence-of-sequences. The generator expression uses tuple(next(flat_
iter) for i in range(5)) to create five tuples from the iterable values in the
flat_iter variable. This expression is nested inside another generator that repeats
the inner loop the proper number of times to create the required sequence of values.


This works only when the flat list is divided evenly. If the last row has partial
elements, we'll need to process them separately.


We can use this kind of function to group data into same-sized tuples, with an odd
sized tuple at the end using the following definitions:


def group_by_seq(n, sequence):
flat_iter=iter(sequence)
full_sized_items = list( tuple(next(flat_iter)
for i in range(n))
for row in range(len(sequence)//n))
trailer = tuple(flat_iter)
if trailer:
return full_sized_items + [trailer]
else:
return full_sized_items


We've created an initial list where each tuple is of the size n. If there are leftovers,
we'll have a trailer tuple with a non-zero length that we can append to the list of
full-sized items. If the trailer tuple is of the length 0, we'll ignore it.

Free download pdf