Skip to content

Instantly share code, notes, and snippets.

@JohnSpeno
Last active September 20, 2019 12:16
Show Gist options
  • Save JohnSpeno/e7911d98148bf63dc7b2 to your computer and use it in GitHub Desktop.
Save JohnSpeno/e7911d98148bf63dc7b2 to your computer and use it in GitHub Desktop.
class PeekIter:
""" Create an iterator which allows you to peek() at the
next item to be yielded. It also stores the exception
and re-raises it on the next next() call.
"""
def __init__(self, iterable):
self._exn = None
self._it = iter(iterable)
self._peek = next(self._it)
def peek(self):
return self._peek
def ok(self):
#True if no exception occured when setting self._peek
return self._exn == None
def __iter__(self):
return iter(self)
def __next__(self):
if self._exn != None:
raise self._exn
t = self._peek
try:
self._peek = next(self._it)
except Exception as exn:
self._exn = exn
self._peek = None
return t
def group_by(iterable):
""" Yield (key, (group))'s of like values
from an iterator.
"""
def group(it):
# Yield only like values.
k = it.peek()
while it.peek() == k:
yield next(it)
itr = PeekIter(iterable)
while itr.ok():
yield itr.peek(), list(group(itr))
print(' '.join(''.join(k) for k, v in group_by('AAAABBBCCDAABBB')))
# 'A B C D A B'
print(' '.join(''.join(g) for k, g in group_by('AAAABBBCCDAABBB')))
# 'AAAA BBB CC D AA BBB'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment