Neil Cerutti
unread,Oct 17, 2012, 12:00:03 PM10/17/12You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to
While working through Project Euler, a fun source of exercises, I
composed the following iterator recipe to yield from multiple
iterators in fixed-length groups:
import itertools
def zip_longest_by(*args, fillvalue=None, n=1, grouper=tuple):
"""Yield n at a time from each of the args, with padding.
It terminates when the longest iterator is exhausted.
>>> for i, j in zip_longest_by("ABCDEFGH", "HIJKL",
... fillvalue="-", n=3, grouper=''.join):
... print(i, j)
ABC HIJ
DEF KL-
GH- ---
>>> for n1, n2 in zip_longest_by(reversed('1234'), reversed('678'),
... fillvalue='0', n=3, grouper=lambda a: ''.join(reversed(a))):
... print(n1, n2)
234 678
001 000
"""
it = itertools.zip_longest(*args, fillvalue=fillvalue)
while True:
accum = list()
try:
for i in range(n):
accum += zip(*next(it))
except StopIteration:
for i in range(n - i):
accum.append(tuple(itertools.repeat(fillvalue, len(args))))
yield tuple(grouper(item) for item in zip(*accum))
break
yield tuple(grouper(item) for item in zip(*accum))
The interface could stand improvement. I find the grouper
argument very convenient, but none of the other grouping
iterators find it needful. Forcing n to be a keyword argument is
unfortunate as well.
--
Neil Cerutti