Produces a list of copies of an iterable that are offset by the supplied offsets.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | import itertools
def offsetter(iterable, offsets=(0, 1), longest=False):
"""
Return offset element from an iterable.
Pad offset element with None at boundaries.
"""
# clone the iterable
clones = itertools.tee(iterable, len(offsets))
# set up the clone iterables
iterables = []
for offset, clone in zip(offsets, clones):
if offset > 0:
# fast forward the start
clone = itertools.islice(clone, offset, None)
elif offset < 0:
# pad the front of the iterable
clone = itertools.chain(itertools.repeat(None, -offset), clone)
else:
# nothing to do
pass
iterables.append(clone)
if longest:
return itertools.izip_longest(*iterables)
else:
return itertools.izip(*iterables)
|
Example:
Use offsetter
to provide a look-ahead and look-backward iterator:
>>> l = range(10)
>>> for prev, curr, next in offsetter(l, offsets=(-1, 0, 1), longest=True):
... print prev, curr, next
None 0 1
0 1 2
1 2 3
2 3 4
3 4 5
4 5 6
5 6 7
6 7 8
7 8 9
8 9 None
9 None None
Nice :)