def ranges(iterable): delimiter = '-' iterable = iter(sorted(set(iterable))) stop = start = iterable.next() while True: try: cur = iterable.next() if cur - stop == 1: stop = cur else: yield yield_range(start, stop, delimiter) stop = start = cur except StopIteration: yield yield_range(start, stop, delimiter) raise StopIteration def yield_range(start, stop, delimiter): if start == stop: return str(stop) else: return "%d%s%d" % (start, delimiter, stop) if __name__ == '__main__': print ', '.join(ranges([1, 1, 2, 3, 5, 6, 11])) print ', '.join(ranges([1, 3, 4, 7, 7, 12, 13])) print ', '.join(ranges([1, 2, 3, 4, 7, 8])) print ', '.join(ranges([13, 17, 20, 27, 28, 29, 50]))