Skip to content

Instantly share code, notes, and snippets.

@rkhullar
Last active March 15, 2023 14:37
Show Gist options
  • Save rkhullar/9ae97a5e76f2071c92a7ce493252eb2b to your computer and use it in GitHub Desktop.
Save rkhullar/9ae97a5e76f2071c92a7ce493252eb2b to your computer and use it in GitHub Desktop.
traverse iterable with prev and next context
from collections.abc import Iterable, Iterator
from typing import TypeVar
T = TypeVar('T')
def _scan(items: Iterable[T]) -> Iterator[tuple[T, T]]:
"""iterator to traverse previous and current items from iterable"""
prev, curr, stream = None, None, iter(items)
while True:
try:
prev = curr
curr = next(stream)
yield prev, curr
except StopIteration:
break
def scan(items: Iterable[T]) -> Iterator[tuple[T, T, T]]:
"""iterator to traverse previous, current, and next items from iterable"""
last, stream = None, _scan(_scan(items))
try:
first = next(stream)
except StopIteration:
return
for x, y in stream:
yield x[0], x[1], y[1]
last = y
if last:
yield last[0], last[1], None
else:
yield None, first[1][1], None
if __name__ == '__main__':
test_input = iter('abc')
for trace in scan(test_input):
print(trace)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment