Example #1
0
 def test_zip_longest(self):
     self.assertEqual([
         list(g)
         for g in python_utils.zip_longest([0, 1, 2, 3], [4, 5, 6], [7, 8])
     ], [[0, 4, 7], [1, 5, 8], [2, 6, None], [3, None, None]])
     # Zip longest with fillvalue.
     self.assertEqual([
         ''.join(g)
         for g in python_utils.zip_longest('ABC', 'DE', 'F', fillvalue='x')
     ], ['ADF', 'BEx', 'Cxx'])
Example #2
0
def grouper(
        iterable: Iterable[T],
        chunk_len: int,
        fillvalue: Optional[T] = None
) -> Iterable[Iterable[T]]:
    """Collect data into fixed-length chunks.

    Source: https://docs.python.org/3/library/itertools.html#itertools-recipes.

    Example:
        grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx

    Args:
        iterable: iterable. Any kind of iterable object.
        chunk_len: int. The chunk size of each group.
        fillvalue: *. The value used to fill out the last chunk in case the
            iterable is exhausted.

    Returns:
        iterable(iterable). A sequence of chunks over the input data.
    """
    # To understand how/why this works, please refer to the following
    # Stack Overflow answer: https://stackoverflow.com/a/49181132/4859885.
    args = [iter(iterable)] * chunk_len
    return python_utils.zip_longest(*args, fillvalue=fillvalue) # type: ignore[no-any-return, no-untyped-call]