Найти - Пользователи
Полная версия: Преобразование списка в строку
Начало » Python для новичков » Преобразование списка в строку
1 2
Stright
Добрый вечер!
Нужно сделать из списка вида:
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
Можно ли сделать это как-то проще и покороче?
terabayt
нужно ли проверять правильность переданного списка?
и если да, то что выводить при передачи “нестандартного” списка?
ajib6ept
Я бы так задачу решил

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
Stright
Точно. Я не учел, что некоторые цифры могут дублироваться и список надо бы отсортировать для начала )
Тогда просто вначале удаляем повторяющиеся цифры и сортируем список, никаких сообщений о дубликатах не выводим. Кстати, а как это лучше удалить повторы? Перебором в цикле или преобразованием во множество, затем в отсортированный список?
terabayt
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
Stright
А как же:
terabayt
-*- Simple is better than complex -*-
?
Большое спасибо за варианты, буду смотреть. А как насчет моего варианта? Там много лишнего?
terabayt
Stright
А как же:
ну немного разнообразия в жизни не помешает:)
Stright
А как насчет моего варианта? Там много лишнего?
ну эт лишнее
#Убираем лишние элементы из строк в списке
# и приводим к строке вида '1-5,7-8,10-12'
мне кажется можно сделать через один прогон
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(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']
работает
terabayt
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])
Shaman
Вариант.
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]]))
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB