The problem got me interested, so I worked on a solution that would not copy anything but only use the original iterator. Posting it here as it relates directly to the question.
class ichunk:
''' An iterable wrapper that raises StopIteration every chunksize+1'th call to __next__ '''
def __init__(self, iterable, chunksize, fill_last_chunk, fill_value):
self.it = iter(iterable)
self.stopinterval = chunksize+1
self.counter = 0
self.has_ended = False
self.fill_last = fill_last_chunk
self.fill_value = fill_value
def __iter__(self):
return self
def __next__(self):
if self.counter > 0 and self.counter % self.stopinterval == 0:
self.counter += 1
raise StopIteration
try:
self.counter += 1
nexti = next(self.it)
return nexti
except StopIteration as e:
self.has_ended = True
if (not self.fill_last) or (self.counter % self.stopinterval == 0):
raise e
else:
return self.fill_value
def ichunker(iterable, chunksize, *, fill_last_chunk=False, fill_value=None):
c = ichunk(iterable, chunksize, fill_last_chunk, fill_value)
while not c.has_ended:
yield c
So rather then using the returned value from ichunker
, you iterate over it again like:
with open("filename") as fp:
for chunk in ichunker(fp, 10):
print("------ start of Chunk -------")
for line in chunk:
print("--> "+line.strip())
print("------ End of Chunk -------")
print("End of iteration")