Batches the elements of given iterable.

    Resulting iterable will yield tuples containing at most ``n`` elements
    (might be less if ``fillvalue`` isn't specified).

    :param n: Number of items in every batch
    :param fillvalue: Value to fill the last batch with. If None, last batch
                      might be shorter than ``n`` elements

    :return: Iterable of batches

    .. note::

        This is an extended version of grouper() recipe
        from the :module:`itertools` module documentation.

def batch(iterable, n, fillvalue=None):
    """Batches the elements of given iterable.

    Resulting iterable will yield tuples containing at most ``n`` elements
    (might be less if ``fillvalue`` isn't specified).

    :param n: Number of items in every batch
    :param fillvalue: Value to fill the last batch with. If None, last batch
                      might be shorter than ``n`` elements

    :return: Iterable of batches

    .. note::

        This is an extended version of grouper() recipe
        from the :module:`itertools` module documentation.
    """
    ensure_iterable(iterable)
    if not isinstance(n, Integral):
        raise TypeError("invalid number of elements in a batch")
    if not (n > 0):
        raise ValueError("number of elements in a batch must be positive")

    # since we must use ``izip_longest``
    # (``izip`` fails if ``n`` is greater than length of ``iterable``),
    # we will apply some 'trimming' to resulting tuples if necessary
    if fillvalue is None:
        fillvalue = object()
        trimmer = lambda item: tuple(x for x in item if x is not fillvalue)
    else:
        trimmer = identity()

    args = [iter(iterable)] * n
    zipped = izip_longest(*args, fillvalue=fillvalue)
    return imap(trimmer, zipped)