Преобразовать список Числа в диапазоны строк

Я хотел бы знать, существует ли простой (или уже созданный) способ сделать обратное: Создать список чисел из дефисов... .Эту ссылку можно использовать для выполнения:

>> list(hyphen_range('1-9,12,15-20,23'))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 15, 16, 17, 18, 19, 20, 23]:

Я хочу сделать обратное (обратите внимание, что 10 и 21 включены, поэтому это будет совместимо с функцией диапазона, где диапазон (1,10) = [1,2, 3,4,5,6,7,8,9]):

>> list_to_ranges([1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 15, 16, 17, 18, 19, 20, 23])
'1-10,12,15-21,23'

В конце концов, я хотел бы, чтобы вывод также включал шаг, где последний номер вывода указывает шаг:

>> list_to_ranges([1, 3, 5, 7, 8, 9, 10, 11])
'1-13:2,8,10'

По существу, это в конечном итоге это что-то вроде «обратной» функции диапазона

>> tmp = list_to_ranges([1, 3, 5])
>> print tmp
'1-7:2'
>> range(1, 7, 2)
[1, 3, 5]

. Я предполагаю, что нет действительно простого/простого способа сделать это, но я подумал, что спрошу здесь, прежде чем приступить к грубой силе, длинному методу.

РЕДАКТИРОВАТЬ

Используя в качестве примера код из ответа на этот пост, я придумал простой способ сделать первую часть. Но я думаю, что определить шаблоны для выполнения шагов будет немного сложнее.

from itertools import groupby
from operator import itemgetter

data = [ 1,  4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
print data, '\n'

str_list = []
for k, g in groupby(enumerate(data), lambda (i,x):i-x):
   ilist = map(itemgetter(1), g)
   print ilist
   if len(ilist) > 1:
      str_list.append('%d-%d' % (ilist[0], ilist[-1]+1))
   else:
      str_list.append('%d' % ilist[0])
print '\n', ','.join(str_list)

РЕДАКТИРОВАТЬ 2

Вот моя попытка включить размер шага... он довольно близок, но первые числа повторяются. Я думаю, что с небольшой настройкой это будет близко к тому, что я хочу, или, по крайней мере, достаточно хорошо.

import numpy as np
from itertools import groupby

def list_to_ranges(data):
   data = sorted(data)
   diff_data = np.diff(data).tolist()
   ranges = []
   i = 0
   for k, iterable in groupby(diff_data, None):
      rng = list(iterable)
      step = rng[0]
      if len(rng) == 1:
         ranges.append('%d' % data[i])
      elif step == 1:
         ranges.append('%d-%d' % (data[i], data[i+len(rng)]+step))
      else:
         ranges.append('%d-%d:%d' % (data[i], data[i+len(rng)]+step, step))
      i += len(rng)
   return ','.join(ranges)

data = [1, 3, 5, 6, 7, 11, 13, 15, 16, 17, 18, 19, 22, 25, 28]
print data
data_str = list_to_ranges(data)
print data_str

_list = []
for r in data_str.replace('-',':').split(','):
   r = [int(a) for a in r.split(':')]
   if len(r) == 1:
      _list.extend(r)
   elif len(r) == 2:
      _list.extend(range(r[0], r[1]))
   else:
      _list.extend(range(r[0], r[1], r[2]))
print _list
print list(set(_list))

7
задан Community 23 May 2017 в 10:31
поделиться