How do I process the elements of a sequence in batches, idiomatically?
For example, with the sequence \"abcdef\" and a batch size of 2, I would like to do something
Except for two answers I saw a lot of premature materialization on the batches, and subscripting (which does not work for all iterators). Hence I came up with this alternative:
def iter_x_and_n(iterable, x, n):
yield x
try:
for _ in range(n):
yield next(iterable)
except StopIteration:
pass
def batched(iterable, n):
if n<1: raise ValueError("Can not create batches of size %d, number must be strictly positive" % n)
iterable = iter(iterable)
try:
for x in iterable:
yield iter_x_and_n(iterable, x, n-1)
except StopIteration:
pass
It beats me that there is no one-liner or few-liner solution for this (to the best of my knowleged). The key issue is that both the outer generator and the inner generator need to handle the StopIteration correctly. The outer generator should only yield something if there is at least one element left. The intuitive way to check this, is to execute a next(...) and catch a StopIteration.