Есть числа по порядку, но с пропусками. Как получить интервалы?
Есть некий интервал чисел с пропусками, например: 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 15, 16, 17, 18, 19, 20. Как получить вместо списка интервалы: 1-3, 5-7, 9-12, 15-20 ?
Ответы (2 шт):
Автор решения: GrAnd
→ Ссылка
Вот так можно:
import itertools
numbers = [1, 2, 3, 5, 6, 7, 9, 10, 12, 15, 16, 17, 18, 19, 20, 25]
ranges = [[r[0][1], r[-1][1]][:len(r)] for r in [list(x) for _, x in itertools.groupby(enumerate(numbers), lambda en: en[0] - en[1])]]
print("List :", ranges)
ranges_str = ", ".join("-".join(map(str, r)) for r in ranges)
print("String :", ranges_str)
D:\Programming\Python\1>python compact_range.py
List : [[1, 3], [5, 7], [9, 10], [12], [15, 20], [25]]
String : 1-3, 5-7, 9-10, 12, 15-20, 25
Автор решения: Stanislav Volodarskiy
→ Ссылка
Функция events выдаёт наружу события. В события включаются концы последовательности чисел и пары чисел окружающих дыры.
Функция ranges соединяет события в пары. Эти пары и есть ответ:
def events(seq):
it = iter(seq)
try:
p = next(it)
except StopIteration:
return
yield p
for v in it:
if p < v - 1:
yield p
yield v
p = v
yield p
def ranges(seq):
return zip(*[iter(events(seq))] * 2)
values = 1, 2, 3, 5, 6, 7, 9, 10, 11, 12, 15, 16, 17, 18, 19, 20
print(*events(values))
print(*ranges(values))
$ python ranges_in_list.py 1 3 5 7 9 12 15 20 (1, 3) (5, 7) (9, 12) (15, 20)