I am trying to make an overlap function in python that takes any iterable, an int n, and an int m (whose default value is 1) as parameters, and produce lists of n values:
- The first list contains the first n values;
- Every subsequent list drops the first m from the previous list
- Adds next m values from the iterator, until there are fewer than n values to put in the returned list.
Example:
for i in overlap('abcdefghijk',4,2):
print(i,end=' ')
Its output is ['a','b','c','d']
, ['c','d','e','f']
, ['e','f','g','h']
, and ['g','h',i','j']
for n=4
and m=2
. In this case if the function is something like this:
def overlap(iterable, n, m=1)
How can this be done? The main problem I am facing is how to stop when there are less than n values.
Current code: credits to anmol_uppal's solution.
def hide(iterable):
for v in iterable:
yield v
def overlap(word, n, m):
start = 0
while(start+n < len(word)):
yield list(word[start:start+n])
start += m
if __name__ == '__main__':
for i in overlap('abcdefghijk',3,2):
print(i, end=' ')
print()
for i in overlap(hide('abcdefghijk'),3,2):
print(i, end=' ')
print()
But the problem is we cannot use len()
with generators.
I have tried this code but I don't know why it's giving unexpected results for the second test case
def hide(iterable):
for v in iterable:
yield v
def window(seq, size, step=1):
iters = [iter(seq) for i in range(size)]
[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(i) for i in iters for j in range(step-1)]
if __name__ == '__main__':
for i in window('abcdefghijk', 3, 2):
print(i, end=' ')
print()
for i in window(hide('abcdefghijk'), 3, 2):
print(i, end=' ')
print()