zip_longest_by

Discussion in 'Python' started by Neil Cerutti, Oct 17, 2012.

  1. Neil Cerutti

    Neil Cerutti Guest

    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
    Neil Cerutti, Oct 17, 2012
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page