8-(927)-977-80-70 web-i-seo@yandex.ru
Режим работы: 10-00 до 20-00 МСК

Вы нашли нас по запросу -"Сравнение методов объединения двух отсортированных списков в Python Дмитров" - это лучшая рекомендация для подрядчика SEO продвижения в городе Дмитров или по России!

Сравнение методов объединения двух отсортированных списков в Python

Пусть у нас есть два списка (для простоты из целых чисел), каждый из которых отсортирован. Хотим объединить их в один список, который тоже должен быть отсортирован. Эта задача наверняка всем знакома, используется, например, при сортировке слиянием.

 

 

Способов реализации (особенно на python) достаточно много. Давайте разберем некоторые из них и сравним затрачиваемое время на разных входных данных.

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

 

Входные данные не меняются

Пусть есть два списка list1 и list2.

Начнем с самого простого алгоритма: обозначим метки за i и j и будем брать меньший из list1[i]list2[j] и увеличивать его метку на единицу, пока одна из меток не выйдет за границу списка.

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

Перейдем к коду:

def simple_merge(list1, list2):
    i, j = 0, 0
    res = []
    while i < len(list1) and j < len(list2):
        if list1[i] < list2[j]:
            res.append(list1[i])
            i += 1
        else:
            res.append(list2[j])
            j += 1
    res += list1[i:]
    res += list2[j:] 
    # один из list1[i:] и list2[j:] будет уже пустой, поэтому добавится только нужный остаток
    return res

 

Заметим, что в данном коде используется только перемещение вперед по списку. Поэтому будет достаточно работать с итераторами. Перепишем алгоритм с помощью итераторов.

 

Еще изменим обработку концов списков, так как теперь мы не умеем копировать сразу до конца. Будем обрабатывать элементы до того, когда оба итератора дойдут до конца, при этом, если один уже оказался в конце, будем просто брать из второго.

 

def iter_merge(list1, list2):
    result, it1, it2 = [], iter(list1), iter(list2)
    el1 = next(it1, None)
    el2 = next(it2, None)
    while el1 is not None or el2 is not None:
        if el1 is None or (el2 is not None and el2 < el1):
            result.append(el2)
            el2 = next(it2, None)
        else:
            result.append(el1)
            el1 = next(it1, None)
    return result

 

В этой реализации можно вместо добавления по одному элементу (result.append()) собрать генератор, а потом из него получить список. Для этого напишем отдельную функцию, которая будет строить генератор, а основная функция сделает из него список.

 

def gen_merge_inner(it1, it2):
    el1 = next(it1, None)
    el2 = next(it2, None)
    while el1 is not None or el2 is not None:
        if el1 is None or (el2 is not None and el2 < el1):
            yield el2
            el2 = next(it2, None)
        else:
            yield el1
            el1 = next(it1, None)

def gen_merge(list1, list2):
    return list(gen_merge_inner(iter(list1), iter(list2))) # из генератора получаем список

 

Встроенные реализации

Рассмотрим еще несколько способов слияния через встроенные в python функции.

  • merge из heapq. Как говорит документация, эта функция делает именно то, что мы хотим, и больше: объединяет несколько итерируемых объекта, можно задать ключ, можно сортировать в обратном порядке.
    Тогда нам нужно просто импортировать и использовать:

    from heapq import merge
    
    def heapq_merge(list1, list2):
        return list(merge(list1, list2)) # тоже возвращает генератор
  • Counter из collectionsCounter умеет считать количество вхождений каждого из элементов, выдавать их в тех количествах, в которых они входят, и еще несколько полезных вещей, которые сейчас не нужны (например, несколько самых часто встречающихся элементов).
    Воспользуемся gen_merge_inner для слияния элементов Counter(list1) и Counter(list2):

    def counter_merge(list1, list2):
        return list(gen_merge_inner(Counter(list1).elements(), Counter(list2).elements()))
  • И, наконец, просто сортировка. Объединяем и сортируем заново. Тут есть два варианта реализация через sort() и sorted(). Сразу сравним их:
list1 = [i for i in range(1, 200000, 3)]
list2 = [i for i in range(2, 250000, 4)]
%timeit res1 = sorted(list1 + list2)
%timeit res2 = list1 + list2; res2.sort()
6.73 ms ± 64.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
4.43 ms ± 38.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

В результате:

    def sort_merge(list1, list2):
        return (list1 + list2).sort()

Если можно менять исходные списки

 

Предположим, что после слияния старые списки больше не нужны (как обычно и случается). Тогда можно написать еще один способ. Будем как и раньше сравнивать нулевые элементы списков и вызывать pop(0) у списка с меньшим, пока один из списков не закончится.

 

def pop_merge(list1, list2):
    result = []
    while list1 and list2:
        result.append((list1 if list1[0] < list2[0] else list2).pop(0))
    return result + list1 + list2

 

Получили простенькую функцию на 4 строчки, но использовать дальше исходные списки не получится. Можно их скопировать, потом работать с копиями, но это потребует много дополнительного времени. Здесь будут проблемы с тем, что удаление нулевого элемента очень дорогое. Поэтому еще одна модификация будет заключаться в том, что мы будем вместо удаления из начала списка использовать удаление из конца, но придется в конце развернуть списки.

 

def reverse_pop_merge(list1, list2):
    result = []
    while list1 and list2:
        result.append((list1 if list1[-1] > list2[-1] else list2).pop(-1))
    return (result + list1[-1::-1] + list2[-1::-1])[-1::-1]

 

Сравнение

 

Пора перейти к самому интересному.
Составим список функций, которые будем сравнивать:

 

  • simple_merge
  • iter_merge
  • gen_merge
  • heapq_merge
  • counter_merge
  • sort_merge
  • pop_merge
  • reverse_pop_merge

 

Будем измерять время работы с помощью модуля timeit. Код можно посмотреть здесь.

 

Разберем несколько ситуаций: оба списка примерно одинакового размера, один список большой, а второй маленький, количество вариантов элементов большое, количество вариантов маленькое. Кроме этого проведем просто общий случайный тест.

Тест первый

 

Проведем общий тест, размеры от $1$ до $10^5$, элементы от $1$ до $10^6$.

 

Отдельно сравним pop и reverse_pop:

 

 

pop_merge тратит колоссально больше времени в общем случае, как и ожидалось.

 

Не будем учитывать здесь огромный pop_merge, чтобы лучше видеть разницу между другими:

 

 

reverse_pop_merge показал себя относительно неплохо по сравнению с ручной реализацией и heapq_merge.

 

Методы на итераторах работают еще быстрее, при этом видно, что получилось выгоднее построить генератор, чем добавлять элементы в список.

 

Тест второй, сравнимые размеры

 

Размеры будут принадлежать отрезку $[50x, 50(x+1))$, а $x$ увеличиваем, начиная с $1$. Шаг $50$.

 

 

Как уже можно видеть pop_merge при небольшом размере списков еще ведет себя как heapq_merge, а дальше обгоняет всех.

 

Тест третий, один маленький, второй большой

 

Размер первого равен $x$, размер второго $10^4 + 100x$.

 

 

В самом начале (на очень маленьких списках) reverse_pop_merge обгоняет всех, кроме sort_merge, но на чуть больших все выходит на стандартные позиции.

 

Тест четвертый, много повторных

 

Размеры фиксированы, а количество элементов увеличивается на $5$, начиная с $1$.

 

 

Как видно, на достаточно малых количествах counter_merge оказывается быстрее reverse_pop_merge и heapq_merge, но потом он отстает.

 

Чемпионы

Абсолютным победителем оказался sort_merge! Гораздо быстрее просто отсортировать список заново, чем использовать вроде бы линейные от длины списков функции.

На втором месте в подавляющем большинстве случаев идет gen_merge, за ним следует iter_merge.

Остальные методы используют еще больше времени, но некоторые в каких-то крайних случаях достигают результатов 2-3 мест.

Дата изменения


Индивидуальный Предприниматель Ознобин Р.А.
8-927-977-80-70
Адрес: г. Дмитров, ул. Строителей, строение 12

Полезная информация по теме - Сравнение методов объединения двух отсортированных списков в Python Дмитров

разработка сайта компании Дмитров

За короткий срок и по доступной цене создание сайта компании Дмитров с последующим обслуживанием и раскруткам. Делаем простые и сложные автоматизированные и продающие on-line витрины и корпоративные площадки. Нашими основными направлениями являются создание и раскрутка порталов компании Дмитров, любой сложности и функционала. Выбирая разработчика Вы увидите большое количество предложений которые усложняют Ваш выбор, особенно если Вы не специалист данной области. Пытаясь самостоятельно разобраться с чего начинается создание портала для компании, Вам придется изучить тонкости on-lineа, стандарты разработки ИТ порталов, оптимизацию программных процессов (скорость загрузки очень важна для посетителей), провести анализ взаимодействия с поисковыми системами и многие другие нюансы разработки — раскрутки порталов. компании занимающиеся разработкой сайтов Дмитров, расскажут Вам хорошую историю, сделают убедительную презентацию, но от куда Вы будете знать, что результат Вас...

Удобный дизайнерский магазин Цветы Люкс Дмитров

Запустили он-лайн магазин «Цветы Люкс» – это современный и элегантный цветочный салон в Самаре, с огромным ассортиментом, подарками и сувенирами ручной усилия, а также предметами декора и интерьера. Заказчик заказал добротный вебсайт on-line магазина, с множеством информации и базовым функционалом on-line магазина цветов. Базовая установка от — 9 600 руб. ! наполнение материалами — от 300 до 1000 руб. за страницу  (в зависимости от наличия и объёмов таблиц, фото и текстов). визуальных эффектов — 10 000 руб.. on-line онлайн магазина — 20 000 руб. Итого: 34 600 руб. + наполнение по желанию Что бы заказать сайт у нас, вам надо лишь отправить заявку с данного сайта или связаться с нами любым из перечисленных в разделе Контакты методов. Сравнение методов объединения двух отсортированных списков в Python — получи СКИДКУ 10% Мы свяжемся с Вами и поможем...

Рост уровня доверия сайта (ТИЦ) с 10 до 80 за 6 месяцев! Дмитров

Серьёзное достижение в области SEO адаптации сайтов! ООО «Комбинат Композитных материалов в августе 2016 года. обратился к нам по вопросам адаптации своего сайта в сети on-line, а также дополнительным задачам по модернизации сайта. За 6 месяцев сайт был не только функционально модернизирован, но так же приобрёл качественно собранное Мета описание (Описание для поисковых роботов) и нарастил ссылочную массу. Это позволило вырастить уровень доверия Яндекса и Гугла с 0 до ТИЦ 80 и GPR 3/6, что в свою очередь привело к росту посещаемости в январе на 166 % ! И позволило предприятию хорошо пережить зиму, сезон низкого спроса. ; ...

поисковое продвижение сайта Дмитров

Лучшая цена на — Поисковое раскрутка сайта Дмитров — и надёжный результат. На протяжении 15 лет, клиенты выбирают нас в качестве специалистов и мы заинтересованы в долгосрочном партнёрстве, что обеспечивает максимальную отдачу и результат. Сегодня все понимают значимость SEO раскрутки сайтов для процветания. Ваши рекламные инвестиции и вложения в раскрутка часто имеют решающее значение для успешного дела. Именно поэтому мы фокусируемся на раскрутка сайта Дмитров в ТОП тех регионов которые интересны Вашему бизнесу. Сравнение методов объединения двух отсортированных списков в Python — получи СКИДКУ 10% Поисковое раскрутка сайта Дмитров оказывает прямое влияние на получение новых клиентов в сети on-line. Такие рекламные траты наиболее эффективны, т.к. Вы получаете целевую аудиторию, уже заинтересованных клиентов в Вашем продукте, товаре или усилийе. Поисковое раскрутка...

Скрыть товары онлайн магазина без артикля. Дмитров

В процессе интеграции онлайн магазина на WordPress и 1С:УНФ, возникла необходимость скрыть товары без артикля (накопившееся в базе данных и не торгуемых в настоящий момент). Запрошено. Сделано! Задача решается добавлением в файл functions.php следующего кода: // Удаляем из запроса товаров, товары без артикля add_action( 'woocommerce_product_query', 'no_sku_pre_get_posts_query' ); function no_sku_pre_get_posts_query( $query ) { $query->set( 'meta_query', array( array( 'key' => '_sku', 'value' => '', 'compare' => '!=' ))); } Таким образом мы перехватываем формирующееся обращение к БД сайта, и добавляем условие не равенства артикля (_sku) пустой строке. ; ...

Интернет решение для Строительно-Монтажной компании Дмитров

Реализован сайт ООО «СМК-Групп» специализируется на создании объектов, структур и сетей связи. ООО «СМК-Групп» решает стратегические системные задачи развития отрасли: от разработки портално-сметной документации до реализации этих порталов «под ключ» с проведением необходимых согласований и получением разрешений на строительство и эксплуатацию объектов. Заказчику понадобился простой информационный портал с перечнем усилий, контактами, технологичным, и лёгким оформлением. Базовая цена составила — 9 600 руб. ! наполнение материалами — от 500 до 1000 руб. за страницу  (в зависимости от наличия и объёмов таблиц, фото и текстов). визуальных эффектов — 5 000 руб.. Что бы заказать вебсайт у нас, вам надо лишь отправить заявку с данного сайта или связаться с нами любым из перечисленных в разделе Контакты методов. Мы свяжемся с Вами и поможем определится с техническим заданием, дизайном и ценой. Сравнение методов объединения двух...

разработка индивидуальных сайтов Дмитров

Если Вы задумались о продвижении бренда на рынке через on-line, то Вам необходима создание индивидуального портала по доступной цене. создание индивидуальных сайтов Дмитров  нужна, что бы показать свое отличительное качество, преимущество или  подчеркнуть Вашу индивидуальность. Конечно любая создание должна включать в себя несколько элементов, способствующих его эффективности и функционалу, а так же хорошую скорость загрузки через мобильный on-line, наличие качественных рекламных предложений, если это продающий а не просто имиджевый портал. Это лишь малая доля того что мы можем сделать для Вас по усилийе создание индивидуального сайта. Узнайте подробнее оставив заявку или связавшись с нашим специалистом. Ваши вопросы и задачи, наша качественная реализация. Создание отличного веб-сайта требует высоких стандартов, как и в  строительстве многоэтажного коммерческого здания. Чтобы добиться успеха, важна правильная архитектура порталов как в первом так и втором случае. Поэтому мы...

продвижение сайта стоимость в месяц Дмитров

раскрутка сайта стоимость в месяц Дмитров зависит от выбранного тарифа, и Ваших потребностей. Более подробно можете ознакомиться с тарифами ниже или позвонив нашему специалисту. раскрутка сайта стоимость в месяц Дмитров — При предоплате за 3-месяца и получи скидку 10%. Вы нашли нас в ТОП10 поиска по запросу «раскрутка сайта стоимость в месяц» Дмитров — это лучшая реклама!!! Ваши потенциальные клиенты вводят свой вопрос в строку поиска, и по этому поисковому запросу появляется результат 10 лучшим предложениям. Раскрутка Вашего портала — оказывается наиболее важной частью маркетинга в настоящее время, так как Ваши клиенты могут найти Вас и совершить покупку или ознакомиться с важной информацией. Выше приведена стоимость в месяц адаптации сайта Независимо от того, как вы рекламируете свой бизнес, у вас должна быть возможность продавать через on-line , где клиенты могут легко найти вас, благодаря оптимизации ...