Skip to content

Instantly share code, notes, and snippets.

@ryanwitt
Created June 12, 2014 19:35
Show Gist options
  • Save ryanwitt/ab7aaf83e996e62c178a to your computer and use it in GitHub Desktop.
Save ryanwitt/ab7aaf83e996e62c178a to your computer and use it in GitHub Desktop.
def collect_ranges(s):
"""
Returns a generator of tuples of consecutive numbers found in the input.
>>> list(collect_ranges([]))
[]
>>> list(collect_ranges([1]))
[(1, 1)]
>>> list(collect_ranges([1,2,3]))
[(1, 3)]
>>> list(collect_ranges([1,5,7,9]))
[(1, 1), (5, 5), (7, 7), (9, 9)]
>>> list(collect_ranges([0,1,2,3,7,8,9,12,13,14,23]))
[(0, 3), (7, 9), (12, 14), (23, 23)]
"""
if len(s) == 0:
pass
elif len(s) == 1:
yield (s[0], s[0])
else:
start = end = s.pop(0)
while len(s):
temp = s.pop(0)
if temp > end + 1:
yield (start, end)
start = end = temp
else:
end = temp
yield (start, end)
if __name__ == '__main__':
# Tests in docstrings
import doctest
doctest.testmod()
# Fuzz tests
import random
for i in range(100):
s = [random.randrange(100) for x in range(random.randrange(100))]
print list(collect_ranges(sorted(s))), sorted(s)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment