Объединение последовательных чисел в кортежи в ряд

У меня есть список вроде

[38, 98, 110, 111, 112, 120, 121, 898] 

Как я могу объединить последовательные числа в пару, представляющую диапазон?

желаемый выход:

 ['38', '98', '110,112', '120,121', '898'] 

Вы можете сделать это с помощью itertools.groupby, заметив, что разница между элементами в вашем списке и счетчиком постоянны, в то время как числа являются последовательными

например

 38 - 0 = 38 98 - 1 = 97 110 - 2 = 108 111 - 3 = 108 112 - 4 = 108 120 - 5 = 115 121 - 6 = 115 898 - 7 = 891 

в этом примере 108's сгруппированы вместе, а 115 сгруппированы вместе. Теперь некоторый код

 >>> from itertools import groupby, count >>> L = [38, 98, 110, 111, 112, 120, 121, 898] >>> groups = groupby(L, key=lambda item, c=count():item-next(c)) >>> tmp = [list(g) for k, g in groups] 

посмотрим, что у нас есть

 >>> tmp [[38], [98], [110, 111, 112], [120, 121], [898]] 

преобразовать в желаемый результат

 >>> [str(x[0]) if len(x) == 1 else "{},{}".format(x[0],x[-1]) for x in tmp] ['38', '98', '110,112', '120,121', '898'] 

Прямое решение:

 def ranger(lst): fr, to = lst[0], lst[0] for x in lst[1:]: if x == to+1: to = x else: yield fr, to fr, to = x, x yield fr, to res = [','.join(map(str, sorted(set(x)))) for x in ranger(lst)]