Форум сайта python.su
16
Добрый вечер!
Нужно сделать из списка вида:
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)
Офлайн
103
нужно ли проверять правильность переданного списка?
и если да, то что выводить при передачи “нестандартного” списка?
Отредактировано terabayt (Март 15, 2015 20:04:10)
Офлайн
26
Я бы так задачу решил
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
Офлайн
16
Точно. Я не учел, что некоторые цифры могут дублироваться и список надо бы отсортировать для начала )
Тогда просто вначале удаляем повторяющиеся цифры и сортируем список, никаких сообщений о дубликатах не выводим. Кстати, а как это лучше удалить повторы? Перебором в цикле или преобразованием во множество, затем в отсортированный список?
Офлайн
103
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
Офлайн
16
А как же:
terabayt?
-*- Simple is better than complex -*-

Офлайн
103
Strightну немного разнообразия в жизни не помешает:)
А как же:
Strightну эт лишнее
А как насчет моего варианта? Там много лишнего?
#Убираем лишние элементы из строк в списке # и приводим к строке вида '1-5,7-8,10-12'
Отредактировано terabayt (Март 15, 2015 22:07:54)
Офлайн
16
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','2','3','4','5','7','8','10','12','15','21','22','23','24']
Отредактировано Stright (Март 15, 2015 22:34:34)
Офлайн
103
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])
Офлайн
88
Вариант.
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)
Офлайн