I believe that what you are looking for is already available as an itertools
recipe; even though pairwise
only allow you to return couples and not tuple of arbitrary length.
You will need to modify it so that:
tee
will return num
iterators;- you advance each of these iterators by one more element than the previous one (see the
consume
recipe for that).
This can lead to the following code:
import itertools def advance(iterator, step): next(itertools.islice(iterator, step, step), None) def tuplewize(iterable, size): iterators = itertools.tee(iterable, size) for position, iterator in enumerate(iterators): advance(iterator, position) return zip(*iterators)
Usage being:
>>> for t in tuplewize(lst, 4): ... print(t) ... (10, 11, 12, 13) (11, 12, 13, 26) (12, 13, 26, 28)
However, you are using numpy
so we may come up with a better numpy approach:
numpy.roll
allows us to advance the nth element on top of the list;numpy.stack
allows us to concatenate the rolled arrays into a single 2D array;numpy.transpose
allows us to convert a "list of lists" into a "list of tuples".
Full code being:
import numpy as np def tuplewize(array, size): if size < 2: return np.array([array]) stack = np.stack([np.roll(array, -i) for i in range(size)]) return np.transpose(stack)[:-size+1]
Usage being:
>>> tuplewise(lst, 4) array([[10, 11, 12, 13], [11, 12, 13, 26], [12, 13, 26, 28]])
And as @Peilonrayz indicated in a comment, a third possibility is to use the more_itertools
package and its windowed
function which has extended capabilities; and as such more overhead, so depending on your needs it may or may not suit you.