Iterate an iterator by chunks (of n) in Python?
Can you think of a nice way (maybe with itertools) to split an iterator into chunks of given size?
Therefore l=[1,2,3,4,5,6,7]
with chunks(l,3)
becomes an iterator [1,2,3], [4,5,6], [7]
I can think of a small program to do that but not a nice way with maybe itertools.
Solution 1:
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
Solution 2:
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.