Пересечение множеств Python: оператор & и intersection
Общие элементы двух множеств одним знаком: & находит тех, кто есть в обоих. Пустое пересечение, isdisjoint и пересечение трёх наборов.
Редакция Питоники
Объединение прошлого урока собирало всех. Пересечение работает наоборот: находит только то, что присутствует в обоих множествах сразу. Кто пришёл оба дня, какие теги у двух статей общие, какие товары есть на обоих складах — все эти вопросы об общих значениях решаются одним знаком &. Операции парные: у оператора есть метод intersection, у пересечения — свойство быть пустым, и отдельная быстрая проверка isdisjoint.
Задача: гости обоих дней
Вернёмся к клубу: в субботу и воскресенье списки гостей частично совпадают. Вопрос дня — кто ходил оба раза, самые преданные гости:
saturday = {'анна', 'борис', 'вера'}
sunday = {'вера', 'глеб', 'анна'}
both_days = saturday & sunday
print(sorted(both_days))
print('пришли оба дня:', len(both_days))
['анна', 'вера'] пришли оба дня: 2
Анна и вера — в обоих списках, остальные гости ходили один раз и в пересечение не попали. Оператор & вернул новое множество из общих элементов; два исходных списка остались целы.
Оператор & и метод intersection
Как и объединение, пересечение пишется двумя записями. Метод intersection делает ровно то же, что &, — это одна операция в двух одеждах:
a = {1, 2, 3}
b = {2, 3, 4}
print(sorted(a & b))
print(sorted(a.intersection(b)))
print(a & b == a.intersection(b))
[2, 3] [2, 3] True
Двойка и тройка — общие: они и есть пересечение. Полезное следствие: пересечение множества с самим собой возвращает копию — все элементы совпадают с собой:
a = {1, 2, 3}
same = a & a
print(sorted(same))
print(a == same)
[1, 2, 3] True
same — новое множество с тем же содержанием: проверка равенства подтверждает. В остальном пересечение ведёт себя как любая операция пары: результат строится заново, источники не трогаются.
intersection принимает список, & — нет
Метод унаследовал правило множеств: перебираемое годится. Поэтому искать общие элементы можно между множеством и списком — например, между тегами статьи и поисковым запросом:
tags_post = {'python', 'web', 'sql'}
search = ['python', 'sql', 'html']
common = tags_post.intersection(search)
print(sorted(common))
['python', 'sql']
Два тега статьи совпали с запросом — intersection сам разобрал список и нашёл общие. Оператор & на том же вызове упадёт: он требует множество с обеих сторон.
a = {1, 2}
a & ['python']
Traceback (most recent call last):
File "app.py", line 2, in <module>
a & ['python']
~~^~~~~~~~~~~~
TypeError: unsupported operand type(s) for &: 'set' and 'list'Общих элементов нет — пустое множество
Что если общих элементов не существует? Пересечение честно вернёт пустое множество — не ошибку и не None. Проверим на чётных и нечётных числах:
even = {2, 4, 6}
odd = {1, 3, 5}
common = even & odd
print(len(common))
print(bool(common))
print(even.isdisjoint(odd))
0 False True
Три ответа о пустоте: длина ноль, булево значение False — пустое множество считается ложью, а метод isdisjoint вернул True: множества действительно не пересекаются. isdisjoint — самый честный вопрос на этот случай: он отвечает сразу True или False, не строя промежуточного множества.
Исходные не меняются; пересечение трёх
Пересечение возвращает новое множество, и исходные наборы остаются полными — это удобно для цепочек: a & b & c вычисляется слева направо и отвечает, что есть во всех трёх сразу:
a = {1, 2, 3}
b = {2, 3, 4}
c = {3, 5}
all_three = a & b & c
print(sorted(all_three))
print(len(a), len(b))
[3] 3 3
Только тройка живёт во всех трёх множествах. Оба исходных набора остались по три элемента: пересечение никого не вычеркнуло, оно собрало новое множество из общих. Метод умеет то же одним вызовом: a.intersection(b, c) принимает несколько аргументов.
Практика: общие теги двух статей
Живой пример на строках: два поста блога, вопрос — какие темы у них общие. Пересечение даёт ответ одной строкой:
post1 = {'python', 'множества', 'уроки'}
post2 = {'python', 'списки', 'уроки'}
common = post1 & post2
print('общих тегов:', len(common))
print(sorted(common))
общих тегов: 2 ['python', 'уроки']
Python и уроки — общие темы, множества и списки — индивидуальные. По той же схеме ищут общих друзей двух профилей, совпадения товаров в корзинах и пересечения аудиторий — везде, где нужно найти общее в двух наборах.
Шпаргалка пересечения
Обе записи операции и вспомогательные проверки — в одной таблице:
| Выражение | Что делает | Особенность |
|---|---|---|
| a & b | Новое множество из общих элементов | Обе стороны — множества |
| a.intersection(b) | То же пересечение, методом | Принимает список и перебираемое |
| a.intersection(b, c) | Общее для трёх и больше | Аргументы через запятую |
| a.isdisjoint(b) | True, если общих нет | Без построения нового множества |
| len(a & b) == 0 | Проверка пустоты вручную | Работает, но isdisjoint читается лучше |
Пересечение нашло общее. Следующая операция пары — разность: что есть у одного множества и отсутствует у другого, со знаком минус и порядком, который здесь впервые станет важным. Ей посвящён урок 8, а задачи на совместные операции множеств ждут в уроке про практику.
Сначала предскажи ответ в голове — это главный навык программиста.
a = {1, 2, 3}
b = {3, 4}
print(sorted(a & b))
print(len(a & b))
x = {'a', 'b'}
y = ['b', 'c']
common = x.intersection(y)
print(sorted(common))
print(len(x), len(y))
even = {2, 4}
odd = {1, 3}
common = even & odd
print(len(common))
print(even.isdisjoint(odd))
1. Что вернёт {1, 2, 3} & {2, 3, 4}?
2. Что вернёт a.intersection([2, 3]), если a — множество {2, 5}?
3. Что произойдёт при a & [2, 3]?
4. Общих элементов у двух множеств нет. Что вернёт a & b?
5. Что означает результат a.isdisjoint(b) == True?
6. Меняет ли пересечение исходные множества?
Даны теги двух статей: post1 = {'python', 'set', 'основы'} и post2 = {'python', 'list', 'основы'}. Найдите общие теги через & и напечатайте две строки: общих N и отсортированный список.
Как найти общие элементы двух множеств в Python?
Оператором & или методом intersection: saturday & sunday вернёт новое множество из элементов, которые есть в обоих наборах. Исходные множества не меняются. Для цепочки из трёх и больше — a & b & c или a.intersection(b, c).
Урок 6: объединение множествЧем оператор & отличается от intersection?
Только требованиями к аргументам. & требует множество с обеих сторон и падает с TypeError на списке; intersection принимает любой перебираемый — список, кортеж — и несколько аргументов сразу. Результат обеих записей одинаков.
Что вернёт пересечение, если общих элементов нет?
Пустое множество: len(a & b) равен 0, bool от него — False. Это не ошибка. Для прямой проверки без построения промежуточного множества есть метод isdisjoint: True означает, что множества не пересекаются.
Как проверить, что множества не пересекаются?
Методом isdisjoint: a.isdisjoint(b) возвращает True, если общих элементов нет, и False, если есть хотя бы один. Вторым аргументом может быть и список. Запись len(a & b) == 0 работает тоже, но строит лишнее множество.
Как найти пересечение множества и списка?
Методом intersection: tags.intersection(['python', 'sql']) найдёт общие элементы множества и списка. Оператор & на списке падает — он требует множество с обеих сторон; список можно обернуть в set и использовать &.
Понравился урок? Сошлитесь на него
«isdisjoint — самый честный вопрос на этот случай: он отвечает сразу True или False, не строя промежуточного множества.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что дальше
Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.
Что читать дальше
Множества · Урок 8
Разность и симметричная разность множеств в Python
Разность отвечает на вопрос «что есть у первого и чего нет у второго», симметричная — «что есть ровно у одного из двух». Операторы - и ^, методы difference и symmetric_difference и почему порядок множеств важен.
Множества · Урок 6
Объединение множеств в Python: оператор | и union
Гости субботы плюс гости воскресенья — но каждый посчитан один раз. Оператор | и метод union собирают два множества в одно без дубликатов.
Множества · Урок 18
Задачи на множества Python: практика с решениями
Четыре задачи на множества из жизни данных: уникальные посетители журнала, общие друзья, первый неповторяющийся элемент и гости, пришедшие оба дня. Код, вывод и разбор каждого шага.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
NumPy · Урок 4
Операции с массивами: векторизация и почему NumPy быстрее списков в 100 раз
Умножаем миллион цен одной строкой и замеряем время через time.perf_counter: почему векторизация NumPy обгоняет цикл for в десятки раз. Ufunc, np.dot, булевы сравнения и правило «никаких for там, где есть операция».
операции с массивами numpyпоэлементные операции numpy
Функции · Урок 3
Return в Python: функция возвращает результат
print показывает значение человеку, return отдаёт программе. Учимся возвращать результат, класть его в переменную и использовать в выражениях — и не путать return с print.
оператор return python
Множества · Урок 17
Множества и словари Python: hash и общие механизмы
Множество и словарь построены на одном механизме: hash назначает каждому элементу полку, и проверка in становится мгновенной. Ключи словаря — готовое множество, над которым работают & и |.
python множества и словариpython dict keys intersection