Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #31522

zip_longest_by

From Neil Cerutti <neilc@norwich.edu>
Newsgroups comp.lang.python
Subject zip_longest_by
Date 2012-10-17 16:00 +0000
Organization Norwich University
Message-ID <ae8303Fpai4U1@mid.individual.net> (permalink)

Show all headers | View raw


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

Back to comp.lang.python | Previous | Next | Find similar | Unroll thread


Thread

zip_longest_by Neil Cerutti <neilc@norwich.edu> - 2012-10-17 16:00 +0000

csiph-web