# Construct intervals from a sequence of numbers and vice versa

What is a Pythonic way to construct intervals from a sequence of integer numbers? E.g. sequence [1, 2, 3, 6, 7, 9] could be converted to ['1-3', '6-7', '9']. I have implemented it like this:

def sequence_to_intervals(seq):
intervals = []
interval_start = None
interval_end = None
for i in sorted(seq):
if interval_start is None:
interval_start = i
interval_end = i
elif interval_end + 1 >= i:
interval_end = i
else:
if interval_start == interval_end:
intervals.append(str(interval_start))
else:
intervals.append(f'{interval_start}-{interval_end}')
interval_start = i
interval_end = i
else:
if interval_start == interval_end:
intervals.append(str(interval_start))
else:
intervals.append(f'{interval_start}-{interval_end}')
return intervals


Simple test:

seq = [1, 2, 3, 6, 7, 9]
sequence_to_intervals(seq)
['1-3', '6-7', '9']


Converting intervals back to sequence:

def intervals_to_sequence(intervals):
seq = []
for interval in intervals:
if '-' in interval:
start, stop = interval.split('-')
seq += list(range(int(start), int(stop) + 1))
else:
seq += [int(interval)]
return seq


Simple test:

intervals = ['1-3', '6-7', '9']
intervals_to_sequence(intervals)
[1, 2, 3, 6, 7, 9]

• interval_end is None is never true. May 11 '19 at 6:48
• @bipll Good remark. Should I remove this check from my question? May 11 '19 at 8:42
• Yes, makes sense. May 11 '19 at 8:58

For the first part of making sequence to intervals, you could do this instead (prob. more Pythonic?) (This can be converted to a function easier - leave for the exercise)

>>> # if x-1 not in seq:  x becomes start point
>>> # if y+1 not in seq:  y becomes end point
>>> starts = [x for x in seq if x-1 not in seq]
>>> ends =  [y for y in seq if y+1 not in seq]
>>> ends
[3, 7, 9]
>>> intervals = [str(a)+'-'+str(b) for a, b in zip(starts, ends)]
>>> intervals
['1-3', '6-7', '9-9']
>>>


[Note - last interval could be 'fixed' too - if we see start_point == end_point. Leave as an exercise.]

Then for the second part, it would be quite similar:

>>> seq = []
>>> for inter in intervals:
s, e = inter.split('-')
seq += list(range(int(s), int(e)+1))
>>> seq
[1, 2, 3, 6, 7, 9]