Работа со списками и кортежем

Напишите функцию, которая принимает список сегментов и возвращает сумму длин всех сегментов. Перекрытие сегментов должно учитываться только один раз. Сегменты — это пары целых чисел в формате кортежа, например: (2, 7) — это интервал от 2 до 7. Длина этого сегмента равна 5. Важно что бы программа мало потребляла памяти на вычисление.

Список с перекрывающимися сегментами: [(2, 5), (8, 11), (4, 6)]. Сумма длин этих сегментов равна 7. Поскольку (2, 5) и (4, 6) перекрываются, мы можем рассматривать интервал как (2, 6), который имеет длину 4.

def sum_my(segments):                                                                
    segments.sort(key=lambda x: x[1])                                                
    new_list = segments                                                              
    new_list_tuples = []                                                             
    for i in range(len(new_list) - 1):                                               
        # если в списке у соседних кортежах 2е числа не равны при i+1                
        if new_list[i][1] + 1 != new_list[i + 1][1]:                                 
            # то вычесляем разницу кортежа и добавляем в новый список                
            new_list_tuples.append(new_list[i][1] - new_list[i][0])                  
            # если равны 2е числа +1                                                 
        if new_list[i][1] + 1 == new_list[i + 1][1]:                                 
            # и у первого кортежа первое число меньше или равно чем у второго кортежа
            if new_list[i][0] <= new_list[i + 1][0]:                                 
                #                                                                    
                new_list_tuples.append(new_list[i + 1][1] - new_list[i][0])          
            else:                                                                    
                new_list_tuples.append(new_list[i + 1][1] - new_list[i + 1][0])      
                                                                                     
    print(new_list)                                                                  
    print(new_list_tuples)    

Проблема застрял не получается создать условие что бы проверяла вдруг больше чем одно слияние подряд должно быть


Ответы (1 шт):

Автор решения: Andrei

Можно вот так решить эту задачу:

list_segments_1 = [(2, 5), (8, 11), (4, 6)]
list_segments_2 = [(1, 2), (2, 5), (-10, 12), (3, 4), (3, 6), (8, 13)]


def sum_of_segments(segments):
    # Создаем объект множества
    # он нам нужен для того чтобы убрать пересечения подмножеств
    result = set()

    # Берем количество сегментов в списке для того
    # чтобы пройтись по всем сегментам
    for i in range(len(segments)):
        # Из каждого сегмента при помощи range генерируем
        # генерируем последовательность чисел 
        # которые заложены в сегменте 
        # (например в сегменте (2, 5)
        # задано множество чисел 2 3 4)
        # Добавляем все числа из всех сегментов
        # в множество result Так как множество хранит только
        # уникальные значения в одном экземпляре все пересечения
        # отсекутся и в итоге мы получим все длины всех сегментов
        # в одном множестве без пересечений. Если взять первый
        # список сегментов то получится вот такое множество
        # {2, 3, 4, 8, 9, 10, 5,} -> 7
        for item in range(segments[i][0], segments[i][1]):
            result.add(item)

    # Соответственно подсчитав длину получившегося множества
    # мы получаем сумму длин подмножеств
    return len(result)


print(sum_of_segments(list_segments_1))
print(sum_of_segments(list_segments_2))
→ Ссылка