Уведомления

Группа в Telegram: @pythonsu

#1 Окт. 27, 2013 09:28:01

alexeyvanzhula
Зарегистрирован: 2012-05-14
Сообщения: 34
Репутация: +  0  -
Профиль   Отправить e-mail  

сокращение последовательности в строке, re

Есть последовательность int-ов, например 4, 10, 346, 1, 3, 123, 6, 2, 5
нужно чтобы функция переводила ее в строку типа ‘1:6, 10, 123, 346 ’
то есть нужно парсить на очередь и очередь записывать в виде ‘start:end’.
Вручную не пробема сделать. Может как-то регекспом?

Офлайн

#2 Окт. 27, 2013 10:07:15

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

сокращение последовательности в строке, re

непонятно же

Офлайн

#3 Окт. 27, 2013 10:17:26

alexeyvanzhula
Зарегистрирован: 2012-05-14
Сообщения: 34
Репутация: +  0  -
Профиль   Отправить e-mail  

сокращение последовательности в строке, re

sergeek
непонятно же

ну как? если встречается последовательность 1,2,3,4 - то она записывается как 1:4

Офлайн

#4 Окт. 27, 2013 11:57:32

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

сокращение последовательности в строке, re

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)))

Офлайн

#5 Окт. 27, 2013 12:33:35

alexeyvanzhula
Зарегистрирован: 2012-05-14
Сообщения: 34
Репутация: +  0  -
Профиль   Отправить e-mail  

сокращение последовательности в строке, re

sergeek

В 2.7 питоне строка x, *xs = ls вызывает синтакс-еррор

Офлайн

#6 Окт. 27, 2013 12:37:57

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

сокращение последовательности в строке, re

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)))

Офлайн

#7 Окт. 27, 2013 12:41:05

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

сокращение последовательности в строке, re

sergeek
А вообще стремновато получается. Может кто-нибудь запостит решение без рекурсии

Офлайн

#8 Окт. 27, 2013 15:57:26

alexeyvanzhula
Зарегистрирован: 2012-05-14
Сообщения: 34
Репутация: +  0  -
Профиль   Отправить e-mail  

сокращение последовательности в строке, re

спасибо, для начала вполне сойдет

Офлайн

#9 Окт. 27, 2013 17:56:56

Budulianin
От:
Зарегистрирован: 2011-10-18
Сообщения: 1218
Репутация: +  33  -
Профиль   Отправить e-mail  

сокращение последовательности в строке, re

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)

Офлайн

#10 Окт. 27, 2013 19:16:46

sergeek
Зарегистрирован: 2012-06-26
Сообщения: 470
Репутация: +  43  -
Профиль   Отправить e-mail  

сокращение последовательности в строке, re

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)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version