I need a rolling window (aka sliding window) iterable over a sequence/iterator/generator. Default Python iteration can be considered a special case, where the window length
def window(seq, size, step=1):
# initialize iterators
iters = [iter(seq) for i in range(size)]
# stagger iterators (without yielding)
[next(iters[i]) for j in range(size) for i in range(-1, -j-1, -1)]
while(True):
yield [next(i) for i in iters]
# next line does nothing for step = 1 (skips iterations for step > 1)
[next(i) for i in iters for j in range(step-1)]
next(it)
raises StopIteration
when the sequence is finished, and for some cool reason that's beyond me, the yield statement here excepts it and the function returns, ignoring the leftover values that don't form a full window.
Anyway, this is the least-lines solution yet whose only requirement is that seq
implement either __iter__
or __getitem__
and doesn't rely on itertools
or collections
besides @dansalmo's solution :)