Уведомления

Группа в Telegram: @pythonsu

#1 Март 15, 2015 19:11:11

Stright
От: Кострома
Зарегистрирован: 2015-01-20
Сообщения: 139
Репутация: +  16  -
Профиль   Отправить e-mail  

Преобразование списка в строку

Добрый вечер!
Нужно сделать из списка вида:

l = ['1','2','3','4','5','7','8','10','12','15','21','22','23','24']
строку вида
s = '1-5,7,8,10,12,15,21-24'
Написал такую функцию:
def list_vyd_to_str(list_vyd):
    '''
    Получение строки со списком выделов вида
    '1-3,5,7,10-12'
    '''
    # Создаем список вида ['1-2-3-4-5','7-8','10-11-12,19,21']
    list1 = []
    for i in range(len(list_vyd)):
        if i == len(list_vyd) - 1:
            list1.append(str(list_vyd[i]))
            break
        elif (int(list_vyd[i+1]) - int(list_vyd[i]) == 1):
            list1.append(str(list_vyd[i]) + '-')
        else:
            list1.append(str(list_vyd[i]) + ',')
    string1 = ''.join(list1)
    list2 = string1.split(',')
    # Убираем лишние элементы из строк в списке
    # и приводим к строке вида '1-5,7-8,10-12'
    list3 = []
    for i in list2:
        # Убираем '-' в строках вида '1-2'
        if ('-' in i and i.count('-') == 1):
            begin = i.find('-')
            end = i.rfind('-')
            string = i[:begin] + ',' + i[end+1:]
            list3.append(string)
        # Убираем '-' в строках вида '1-2-3-4'
        elif ('-' in i and i.count('-') > 1):
            begin = i.find('-')
            end = i.rfind('-')
            string = i[:begin] + '-' + i[end+1:]
            list3.append(string)
        # Добавляем строки из одной цифры
        else:
            list3.append(i)
    result_list = ','.join(list3)
    return result_list
Можно ли сделать это как-то проще и покороче?

Отредактировано Stright (Март 15, 2015 19:15:34)

Офлайн

#2 Март 15, 2015 20:03:32

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Преобразование списка в строку

нужно ли проверять правильность переданного списка?
и если да, то что выводить при передачи “нестандартного” списка?



————————————————
-*- Simple is better than complex -*-

Отредактировано terabayt (Март 15, 2015 20:04:10)

Офлайн

#3 Март 15, 2015 20:40:29

ajib6ept
От: От: От: От: От: От: От: От:
Зарегистрирован: 2013-08-04
Сообщения: 297
Репутация: +  26  -
Профиль   Отправить e-mail  

Преобразование списка в строку

Я бы так задачу решил

out = ''
lst = ['1','2','3','4','5','7','8','10','12','15','21','22','23','24']
lst = [int(l) for l in lst]
def check_lst():
    for k, v in enumerate(range(lst[0], lst[::-1][0])):
        if v not in lst:
            return k
    else:
        return len(lst)
while lst:
    t = check_lst() 
    if t > 2:
        out += '%s-%s,' % (lst[0], lst[t-1])
        lst = lst[t:]
    else:
        out += '%s,' % lst[0]
        lst = lst[1:]
out = out[:len(out)-1] 
print out



_________________________
Python golden rule: Do not PEP 8 unto others; only PEP 8 thy self.
Don't let PEP 8 make you insanely intolerant of other people's code.

Офлайн

#4 Март 15, 2015 20:46:58

Stright
От: Кострома
Зарегистрирован: 2015-01-20
Сообщения: 139
Репутация: +  16  -
Профиль   Отправить e-mail  

Преобразование списка в строку

Точно. Я не учел, что некоторые цифры могут дублироваться и список надо бы отсортировать для начала )
Тогда просто вначале удаляем повторяющиеся цифры и сортируем список, никаких сообщений о дубликатах не выводим. Кстати, а как это лучше удалить повторы? Перебором в цикле или преобразованием во множество, затем в отсортированный список?

Офлайн

#5 Март 15, 2015 21:48:13

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Преобразование списка в строку

ajib6ept

out = ''
lst = ['1','3','4','5','7','8','9','10','12','15','21','22','23','25']
#lst = [int(l) for l in lst]
lst = map(int, lst)
def check_lst():
    #for k, v in enumerate(range(lst[0], lst[::-1][0])):
    for k, v in enumerate(range(lst[0], lst[-1])):
        if v not in lst:
            return k
    #else:
    return len(lst)
while lst:
    t = check_lst() 
    if t > 2:
        out += '%s-%s,' % (lst[0], lst[t-1])
        lst = lst[t:]
    else:
        out += '%s,' % lst[0]
        lst = lst[1:]
out = out[:len(out)-1] 
print out
немного извращения)))
list_vyd_to_str = lambda array: ','.join(['%s-%s' % (a+1, b-1) if b - a > 3 else ','.join(map(str, range(a+1, b))) for a, b in zip(list(set(range(int(array[0])-1, int(array[-1])+2)) - set(map(int, array))), (list(set(range(int(array[0])-1, int(array[-1])+2)) - set(map(int, array))))[1:]) if b - a > 1])
>>> list_vyd_to_str = lambda array: ','.join(['%s-%s' % (a+1, b-1) if b - a > 3 else ','.join(map(str, range(a+1, b))) for a, b in zip(list(set(range(int(array[0])-1, int(array[-1])+2)) - set(map(int, array))), (list(set(range(int(array[0])-1, int(array[-1])+2)) - set(map(int, array))))[1:]) if b - a > 1])
>>> print list_vyd_to_str(['1','2','3','4','5','7','8','10','12','15','21','22','23','24'])
1-5,7,8,10,12,15,21-24



————————————————
-*- Simple is better than complex -*-

Офлайн

#6 Март 15, 2015 22:00:49

Stright
От: Кострома
Зарегистрирован: 2015-01-20
Сообщения: 139
Репутация: +  16  -
Профиль   Отправить e-mail  

Преобразование списка в строку

А как же:

terabayt
-*- Simple is better than complex -*-
?
Большое спасибо за варианты, буду смотреть. А как насчет моего варианта? Там много лишнего?

Офлайн

#7 Март 15, 2015 22:07:42

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Преобразование списка в строку

Stright
А как же:
ну немного разнообразия в жизни не помешает:)
Stright
А как насчет моего варианта? Там много лишнего?
ну эт лишнее
#Убираем лишние элементы из строк в списке
# и приводим к строке вида '1-5,7-8,10-12'
мне кажется можно сделать через один прогон



————————————————
-*- Simple is better than complex -*-

Отредактировано terabayt (Март 15, 2015 22:07:54)

Офлайн

#8 Март 15, 2015 22:31:50

Stright
От: Кострома
Зарегистрирован: 2015-01-20
Сообщения: 139
Репутация: +  16  -
Профиль   Отправить e-mail  

Преобразование списка в строку

terabayt
Наверное, где-то ошибочка

>>> list_vyd_to_str = lambda array: ','.join(['%s-%s' % (a+1, b-1) if b - a > 3 else ','.join(map(str, range(a+1, b))) for a, b in zip(list(set(range(int(array[0])-1, int(array[-1])+2)) - set(map(int, array))), (list(set(range(int(array[0])-1, int(array[-1])+2)) - set(map(int, array))))[1:]) if b - a > 1])
>>> print list_vyd_to_str(['1','2','3','4','5','7','8'])
1-8
А должно быть: 1-5,7,8
Хотя на таком списке
['1','2','3','4','5','7','8','10','12','15','21','22','23','24']
работает

Отредактировано Stright (Март 15, 2015 22:34:34)

Офлайн

#9 Март 15, 2015 22:46:21

terabayt
От: Киев
Зарегистрирован: 2011-11-26
Сообщения: 1099
Репутация: +  103  -
Профиль   Отправить e-mail  

Преобразование списка в строку

Stright
terabaytНаверное, где-то ошибочка
та весь код ошибка))
забыл отсортировать, теперь должен работать
list_vyd_to_str = lambda array: ','.join(['%s-%s' % (a+1, b-1) if b - a > 3 else ','.join(map(str, range(a+1, b))) for a, b in zip(sorted(list(set(range(int(array[0])-1, int(array[-1])+2)) - set(map(int, array)))), sorted(list(set(range(int(array[0])-1, int(array[-1])+2)) - set(map(int, array))))[1:]) if b - a > 1])



————————————————
-*- Simple is better than complex -*-

Офлайн

#10 Март 15, 2015 22:53:16

Shaman
Зарегистрирован: 2013-03-15
Сообщения: 1369
Репутация: +  88  -
Профиль   Отправить e-mail  

Преобразование списка в строку

Вариант.

l = ['1','2','3','4','5','7','8','10','12','15','21','22','23','24']
def rf(a, b):
    if abs(int(a[-1]) - int(b)) == 1:
        if len(a) > 1 and a[-2] == '-':
            a[-1] = b
            return a
        return a + ['-', b]
    return a + [',', b]
print ''.join(reduce(rf, l[1:], [l[0]]))

Отредактировано Shaman (Март 16, 2015 15:29:10)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version