37 lines
1011 B
Python
37 lines
1011 B
Python
class PushableIter():
|
|
"Can push items back on iterable"
|
|
def __init__(self, it):
|
|
self.it = iter(it)
|
|
self.pushed = []
|
|
|
|
def push(self, item):
|
|
self.pushed.append(item)
|
|
|
|
def pop(self):
|
|
return self.pushed.pop(0) if self.pushed else self.it.__next__()
|
|
|
|
def __iter__(self):
|
|
return self
|
|
|
|
def __next__(self):
|
|
return self.pop()
|
|
|
|
def range_extractp(sorted_iterable):
|
|
'Yield 2-tuple ranges or 1-tuple single elements from iter of increasing ints'
|
|
rest = PushableIter(sorted_iterable)
|
|
for this in rest:
|
|
low = hi = last = this
|
|
for nxt in rest: # Find upper range on incremented values
|
|
if nxt == last + 1:
|
|
last = hi = nxt
|
|
else: # Out of (sub)-range
|
|
rest.push(nxt)
|
|
break
|
|
if hi - low >= 2:
|
|
yield (low, hi)
|
|
elif hi - low == 1:
|
|
yield (low,)
|
|
yield (hi,)
|
|
else:
|
|
yield (low,)
|