Skip to content

Instantly share code, notes, and snippets.

@purpleP
Created March 6, 2018 23:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save purpleP/5c48273c71893fc39c80ac4afb52536f to your computer and use it in GitHub Desktop.
Save purpleP/5c48273c71893fc39c80ac4afb52536f to your computer and use it in GitHub Desktop.
split
class split:
def __init__(self, delimiter, sequence):
"""
Break a sequence on particular elements.
Return an iterator over chunks.
Arguments:
delimiter if a function, it returns True on chunk separators;
otherwise, it is the value of chunk separator.
sequence original sequence;
keepdelims whether or not to keep delimiters in chunks
"""
self.delimiter = delimiter(x) if callable(delimiter) else partial(eq, delimiter)
self.sequence = iter(sequence)
self.active = OrderedDict()
self.id = 0
self.last_yielded_subgen_id = 0
def __iter__(self):
return self
def subgen(self, id, item, buffered):
if self.delimiter(item):
return
yield item
buffered = self.active[id][1]
while True:
if buffered:
yield from (buffered.popleft() for i in range(len(buffered)))
elif id not in self.active:
return
else:
try:
item = next(seq)
except StopIteration:
self.active.pop(id)
return
else:
is_delim = self.delimiter(item)
if is_delim:
if self.active:
self.active.popitem(last=False)
else:
if self.active:
self.active[0][1].append(item)
else:
yield item
def __next__(self):
if self.active:
yield self.active[min(self.active)][0]
else:
try:
item = next(self.sequence)
except StopIteration:
return
else:
buffer = deque()
self.id += 1
subg = self.subgen(id, item, buffer)
self.active[id] = subg, buffer
yield subg
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment