filmov
tv
Пересечение списков. Совпадающие элементы двух списков. Решение задачи на Python.
Показать описание
Есть такая задача в программировании как поиск совпадающих элементов двух списков. Иногда говорят "пересечение списков". Но на самом деле "пересечение списков" и "поиск совпадающих элементов" – это несколько разные вещи. Понятие "пересечение" правильнее употреблять по отношению к множествам, потому что в отдельно взятом множестве не может быть двух одинаковых элементов. А в списке может.
Если все же речь идет о пересечении списков, в которых нет повторяющихся значений, или даже есть, но это не важно для результирующего списка, то задачу в Python можно решить одним выражением: через преобразование списков во множества и выполнение операции пересечения множеств.
А вот когда речь идет о поиске общих элементов и есть повторяющиеся значения, то задача становится куда сложнее. Например, в этом списке у нас три четверки, а в этом две. В результат должны попасть две четверки, потому что они как бы совпадают в двух списках.
Начнем с простого – с пересечения. С помощью функции set преобразуем первый список во множество и второй. Операция пересечения в Питоне обозначается знаком амперсанда. Результатом этой операции является новое множество. Поскольку нам надо получить список, создадим его с помощью функции list.
Теперь решим задачу, как-будто мы ничего не знаем о множествах. Каким будет алгоритм поиска совпадающих элементов? Например, мы можем брать по очереди элементы первого списка и проверять, есть ли такие во втором.
Итак, в цикле for перебираем элементы списка 'a'. На каждой итерации цикла будет браться очередной элемент. Если он есть и во втором списке, то будем добавлять его в третий.
Обратите внимание, что смысл этих похожих выражений зависит от контекста, то есть от того, при какой инструкции они находятся. При цикле for – это извлечение каждого следующего элемента перед каждым проходом по телу цикла. При инструкции if – это логическое выражение, которое возвращает истину, если такой элемент встречается в этом списке.
Теперь посмотрим, что будет, если в первом списке есть два совпадающих элемента.
В результат попадают оба. Почему? Логическое выражение при if возвращает истину, и когда проверяется этот элемент на вхождение в 'b', и когда проверяется этот. Поэтому он добавляется два раза.
Чтобы решить проблему, мы можем расширить условие, добавив проверку на невхождение в 'c'.
Когда проверяется вторая четверка, это выражение возвращает истину, а это – ложь. Потому что проверяется, что значения нет в 'c'. А в данном случае оно там уже есть.
Но если мы добавим вторую четверку во второй список, то в результате должны быть две четверки, а у нас по-прежнему будет одна.
Для решения этой проблемы должен быть код, который подсчитывает, сколько раз каждое значение встречается в каждом списке и сравнивает эти количества между собой.
Итак, этот код дает нам пересечение списков, каждый элемент в нем уникален. Будем перебирать элементы уже этого списка и считать количество подобных значений в каждом из исходных списков.
Метод count возвращает, сколько раз значение аргумента встречается в списке, к которому применяется метод. Если в этих списках элемент встречается столько же раз, сколько уже есть в 'c', то делать ничего не надо. Но может быть в обоих его больше, чем в 'c', и в том и в другом. Если это так, тогда надо узнать, в каком из двух списков его все же меньше. Для этого воспользуемся функцией min. Она возвращает минимальное из переданных аргументов.
И вот в таком количестве нам надо будет добавить одинаковых элементов в 'c'. Но поскольку один там уже есть, то надо вычесть единицу.
Если все же речь идет о пересечении списков, в которых нет повторяющихся значений, или даже есть, но это не важно для результирующего списка, то задачу в Python можно решить одним выражением: через преобразование списков во множества и выполнение операции пересечения множеств.
А вот когда речь идет о поиске общих элементов и есть повторяющиеся значения, то задача становится куда сложнее. Например, в этом списке у нас три четверки, а в этом две. В результат должны попасть две четверки, потому что они как бы совпадают в двух списках.
Начнем с простого – с пересечения. С помощью функции set преобразуем первый список во множество и второй. Операция пересечения в Питоне обозначается знаком амперсанда. Результатом этой операции является новое множество. Поскольку нам надо получить список, создадим его с помощью функции list.
Теперь решим задачу, как-будто мы ничего не знаем о множествах. Каким будет алгоритм поиска совпадающих элементов? Например, мы можем брать по очереди элементы первого списка и проверять, есть ли такие во втором.
Итак, в цикле for перебираем элементы списка 'a'. На каждой итерации цикла будет браться очередной элемент. Если он есть и во втором списке, то будем добавлять его в третий.
Обратите внимание, что смысл этих похожих выражений зависит от контекста, то есть от того, при какой инструкции они находятся. При цикле for – это извлечение каждого следующего элемента перед каждым проходом по телу цикла. При инструкции if – это логическое выражение, которое возвращает истину, если такой элемент встречается в этом списке.
Теперь посмотрим, что будет, если в первом списке есть два совпадающих элемента.
В результат попадают оба. Почему? Логическое выражение при if возвращает истину, и когда проверяется этот элемент на вхождение в 'b', и когда проверяется этот. Поэтому он добавляется два раза.
Чтобы решить проблему, мы можем расширить условие, добавив проверку на невхождение в 'c'.
Когда проверяется вторая четверка, это выражение возвращает истину, а это – ложь. Потому что проверяется, что значения нет в 'c'. А в данном случае оно там уже есть.
Но если мы добавим вторую четверку во второй список, то в результате должны быть две четверки, а у нас по-прежнему будет одна.
Для решения этой проблемы должен быть код, который подсчитывает, сколько раз каждое значение встречается в каждом списке и сравнивает эти количества между собой.
Итак, этот код дает нам пересечение списков, каждый элемент в нем уникален. Будем перебирать элементы уже этого списка и считать количество подобных значений в каждом из исходных списков.
Метод count возвращает, сколько раз значение аргумента встречается в списке, к которому применяется метод. Если в этих списках элемент встречается столько же раз, сколько уже есть в 'c', то делать ничего не надо. Но может быть в обоих его больше, чем в 'c', и в том и в другом. Если это так, тогда надо узнать, в каком из двух списков его все же меньше. Для этого воспользуемся функцией min. Она возвращает минимальное из переданных аргументов.
И вот в таком количестве нам надо будет добавить одинаковых элементов в 'c'. Но поскольку один там уже есть, то надо вычесть единицу.
Комментарии