Iterate an iterator by chunks (of n) in Python?
Although OP asks function to return chunks as list or tuple, in case you need to return iterators, then Sven Marnach's solution can be modified:
def grouper_it(n, iterable):
it = iter(iterable)
while True:
chunk_it = itertools.islice(it, n)
try:
first_el = next(chunk_it)
except StopIteration:
return
yield itertools.chain((first_el,), chunk_it)
Some benchmarks: http://pastebin.com/YkKFvm8b
It will be slightly more efficient only if your function iterates through elements in every chunk.
The grouper()
recipe from the itertools
documentation's recipes comes close to what you want:
def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
It will fill up the last chunk with a fill value, though.
A less general solution that only works on sequences but does handle the last chunk as desired is
[my_list[i:i + chunk_size] for i in range(0, len(my_list), chunk_size)]
Finally, a solution that works on general iterators and behaves as desired is
def grouper(n, iterable):
it = iter(iterable)
while True:
chunk = tuple(itertools.islice(it, n))
if not chunk:
return
yield chunk