Форум сайта python.su
Есть последовательность int-ов, например 4, 10, 346, 1, 3, 123, 6, 2, 5
нужно чтобы функция переводила ее в строку типа ‘1:6, 10, 123, 346 ’
то есть нужно парсить на очередь и очередь записывать в виде ‘start:end’.
Вручную не пробема сделать. Может как-то регекспом?
Офлайн
непонятно же
Офлайн
sergeek
непонятно же
Офлайн
alexeyvanzhulaнет
Может как-то регекспом?
def intervals(ls): x, *xs = ls if xs: if xs[0] - x == 1: if len(xs) == 1: return '{}:{}'.format(x, xs[0]) last, nxs = _take_last(xs) return '{}:{}, {}'.format(x, last, intervals(nxs)) return '{}, {}'.format(x, intervals(xs)) return str(x) def _take_last(ls): x, *xs = ls if xs[0] - x == 1: return _take_last(xs) return x, xs l = [4, 10, 346, 1, 3, 123, 6, 2, 5] print(intervals(sorted(l)))
Офлайн
sergeek
Офлайн
alexeyvanzhula
В 2.7 питоне строка x, *xs = ls вызывает синтакс-еррор
def intervals(ls): x, xs = ls[0], ls[1:] if xs: if xs[0] - x == 1: if len(xs) == 1: return '{}:{}'.format(x, xs[0]) last, nxs = _take_last(xs) return '{}:{}, {}'.format(x, last, intervals(nxs)) return '{}, {}'.format(x, intervals(xs)) return str(x) def _take_last(ls): x, xs = ls[0], ls[1:] if xs[0] - x == 1: return _take_last(xs) return x, xs l = [4, 10, 346, 1, 3, 123, 6, 2, 5] print(intervals(sorted(l)))
Офлайн
sergeekА вообще стремновато получается. Может кто-нибудь запостит решение без рекурсии
Офлайн
спасибо, для начала вполне сойдет
Офлайн
sergeek
А вообще стремновато получается. Может кто-нибудь запостит решение без рекурсии
lst = [2, 3, 4, 5, 6, 10, 20, 45, 77, 78, 79, 87, 96, 97, 98, 0, 123, 124, 125, 126] lst.sort() enum_lst = [] enum_tup_lst = [] num_prev = lst[0] result_lst = [] for enum, num in enumerate(lst[1:]): if num - num_prev == 1 and num != lst[-1]: enum_lst.append(enum) num_prev = num elif len(enum_lst) > 1: enum_lst.append(enum) if num == lst[-1] and num - lst[-2] == 1: enum_lst.append(enum+1) enum_tup_lst.append([enum_lst[0], enum_lst[-1]]) enum_lst = [] num_prev = num else: num_prev = num it = iter(enumerate(lst)) borders_it = iter(enum_tup_lst) border = next(borders_it) for enum, num in it: try: if border[0] <= enum <= border[1]: result_lst.append( ':'.join( [str( lst[border[0]] ), str( lst[border[1]] )] ) ) for i in xrange(border[1] - enum): next(it) border = next(borders_it) else: result_lst.append(num) except StopIteration: for enum, num in it: result_lst.append(num) print(lst) print(result_lst)
[0, 2, 3, 4, 5, 6, 10, 20, 45, 77, 78, 79, 87, 96, 97, 98, 123, 124, 125, 126] [0, '2:6', 10, 20, 45, '77:79', 87, '96:98', '123:126']
[1, 2, 3, 4, 5, 6, 10, 123, 346] ['1:6', 10, 123, 346]
Отредактировано Budulianin (Окт. 27, 2013 17:59:55)
Офлайн
Budulianinна этих данных мой вариант валится[0, 2, 3, 4, 5, 6, 10, 20, 45, 77, 78, 79, 87, 96, 97, 98, 123, 124, 125, 126]
def intervals(ls): x, xs = ls[0], ls[1:] if xs: if xs[0] - x == 1: if len(xs) == 1: return '{}:{}'.format(x, xs[0]) last, nxs = _take_last(xs) if nxs: return '{}:{}, {}'.format(x, last, intervals(nxs)) return '{}:{}'.format(x, last) return '{}, {}'.format(x, intervals(xs)) return str(x) def _take_last(ls): x, xs = ls[0], ls[1:] if xs: if xs[0] - x == 1: return _take_last(xs) return x, xs return x, xs l = [0, 2, 3, 4, 5, 6, 10, 20, 45, 77, 78, 79, 87, 96, 97, 98, 123, 124, 125, 126] print(intervals(sorted(l)))
Отредактировано sergeek (Окт. 27, 2013 19:17:22)
Офлайн