Подмножества в Python: issubset и issuperset
Один комплект внутри другого: issubset и issuperset возвращают True или False одной строкой. Строгие знаки < и >, пустое множество, списки вместо множеств и направления проверки.
Редакция Питоники
Пересечение из урока 7 показывало, что общего, разность из урока 8 — чего не хватает. Остался последний вопрос про пару множеств: вкладывается ли один комплект в другой. Склад и минимальная закупка, обязательные поля и заполненная форма, инструменты и рюкзак — везде спрашивают: всё ли нужное на месте. Ответ — флаг True или False, одной строкой без циклов.
issubset: всё ли из нужного есть
need — что требуется, stock — что есть на складе. Проверяем, можно ли собрать комплект без докупки:
need = {'молоток', 'гвозди'}
stock = {'гвозди', 'молоток', 'пила', 'уровень'}
print(need.issubset(stock))
print(need <= stock)
True True
Метод и оператор <= отвечают одинаково: всё из need нашлось в stock. Оператор читается как «меньше или равно»: левое множество не больше правого по составу, каждый его элемент есть в правом.
issuperset: тот же вопрос с другой стороны
Можно спросить и наоборот: покрывает ли склад потребность. Метод issuperset и оператор >= — зеркальный взгляд на ту же проверку:
need = {'молоток', 'гвозди'}
stock = {'гвозди', 'молоток', 'пила', 'уровень'}
print(stock.issuperset(need))
print(stock >= need)
print(need.issubset(stock) == stock.issuperset(need))
True True True
a.issubset(b) и b.issuperset(a) — одна и та же проверка с двух сторон. Выбирайте ту формулировку, которая читается естественно: склад покрывает заказ или заказ входит в склад. Смысл не меняется — меняется только точка зрения.
Когда чего-то не хватает
Если комплект не собирается, ответ False — а разность из урока 8 подскажет, чего именно не хватает:
need = {'молоток', 'шуруповёрт'}
stock = {'гвозди', 'молоток', 'пила'}
print(need.issubset(stock))
print(sorted(need - stock))
False ['шуруповёрт']
Пара «флаг плюс разность» — типичный ход: сначала быстрый вопрос, потом список недостающего для сообщения пользователю. Флаг решает, пускать ли дальше; разность объясняет, что докупить.
Строгие знаки: < и >
<= засчитывает и полное равенство: равные множества — подмножества друг друга. Если нужно именно строгое вложение — внутри есть лишнее, — берут < и >:
small = {'чай', 'кофе'}
big = {'чай', 'кофе', 'какао'}
print(small < big)
print(small <= big)
print(small <= small)
print(small < small)
True True True False
Чай и кофе — собственное подмножество большого набора: < подтверждает, ведь в big есть лишнее какао. А само с собой множество сравнивается только нестрого: < даёт False, потому что множества равны, и «внутри» ничего лишнего нет.
Пустое множество и равные комплекты
Два крайних случая полезно знать заранее. Пустое множество — подмножество любого множества: в нём нет ни одного элемента, который мог бы не найтись. А равные множества — подмножества друг друга: проверка <= отвечает True в обе стороны, что бы ни говорил порядок перечисления.
empty = set()
stock = {'чай', 'кофе'}
print(empty.issubset(stock))
print(stock <= stock)
print({'чай', 'кофе'} == {'кофе', 'чай'})
True True True
Порядок в множестве ничего не значит — об этом урок 1: одинаковые комплекты равны независимо от того, в какой последовательности их записали. Поэтому третий ответ True.
Метод принимает список, оператор — нет
Как и методы разности, issubset и issuperset принимают любую коллекцию. Удобно: проверить команду против списка обязательных имён можно без превращения списка в множество. Глеб не входит в список обязательных — метод отвечает False:
team = {'Анна', 'Глеб'}
required = ['Анна', 'Борис', 'Вера']
print(team.issubset(required))
False
team = {'Анна', 'Глеб'}
required = ['Анна', 'Борис', 'Вера']
print(team <= required)
Traceback (most recent call last):
File "app.py", line 4, in <module>
print(team <= required)
^^^^^^^^^^^^^^^^
TypeError: '<=' not supported between instances of 'set' and 'list'Сообщение честно называет пару типов: между set и list сравнение <= не поддерживается. Правило то же, что у разности: операторы — для множеств, методы — для всего подряд.
Проверка комплектов на практике
required = {'email', 'имя'}
filled = {'email', 'имя', 'телефон'}
print(required <= filled)
print(sorted(filled - required))
True ['телефон']
Обязательные поля на месте, телефон — необязательное дополнение. Обратная задача — поймать пропуски — записывается той же парой: флаг решает, а разность перечисляет, чего не хватает.
| Вопрос | Метод | Оператор |
|---|---|---|
| a вкладывается в b? | a.issubset(b) | a <= b |
| a строго внутри b? | нет отдельного метода | a < b |
| a покрывает b? | a.issuperset(b) | a >= b |
| a строго покрывает b? | нет отдельного метода | a > b |
Что дальше
На проверках вкладывания семья операций множеств завершена: добавление, удаление, поиск, объединение, пересечение, разность и подмножества покрывают повседневную работу. Дальше — первый гость из мира неизменяемости: в уроке 10 знакомимся с frozenset, множеством, которое нельзя менять, и узнаём, зачем оно словарям.
Сначала предскажи ответ в голове — это главный навык программиста.
a = {1, 2}
b = {1, 2, 3}
print(a <= b)
print(a < b)
print(b < b)
have = {'зонт', 'шляпа'}
needed = {'зонт'}
print(needed <= have)
print(sorted(have - needed))
required = {'email'}
filled = set()
print(required <= filled)
print(filled <= required)
1. Что вернёт {'а'} <= {'а', 'б'}?
2. Что проверяет stock.issuperset(need)?
3. Чем < отличается от <=?
4. Верно ли, что пустое множество — подмножество любого?
5. Что произойдёт при вычислении team <= ['Анна', 'Борис']?
6. Чему равносильна проверка a.issubset(b)?
7. required = set(). Что вернёт required <= filled для любой формы?
Даны required = {'логин', 'пароль'} и filled = {'пароль', 'логин', 'email'}. Проверьте одной строкой, что обязательные поля заполнены, затем выведите sorted-список того, что заполнено сверх обязательного.
Что такое подмножество в Python?
Множество a — подмножество b, если каждый элемент a есть в b. Проверяется методом issubset или оператором <=: need <= stock вернёт True или False одной строкой, без циклов.
Урок 7: пересечение множествЧем issubset отличается от in?
in проверяет один элемент, issubset — весь комплект разом. Десять подряд идущих проверок in заменяются одним <=. Одиночная проверка при этом остаётся мгновенной — об этом урок 5 курса.
Урок 5: in — мгновенная проверкаЧем issubset отличается от issuperset?
Направлением вопроса: a.issubset(b) спрашивает, вкладывается ли a в b, а a.issuperset(b) — покрывает ли a всё из b. Это одна и та же проверка, записанная с разных сторон: a.issubset(b) равносильно b.issuperset(a).
Сравнятся ли множество и список?
Методы — да: need.issubset([список]) принимает любую коллекцию. Операторы <= и >= — нет: они падают с TypeError, требуют множества с обеих сторон.
Почему set() <= s всегда True?
В пустом множестве нет элементов, которые могли бы не найтись в s, поэтому проверка вкладывания всегда проходит. Практический вывод: пустой список обязательных требований пропускает любую валидацию — следите, чтобы он был заполнен.
Понравился урок? Сошлитесь на него
«Пустое множество — подмножество любого множества: в нём нет ни одного элемента, который мог бы не найтись.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что дальше
Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.
Что читать дальше
Множества · Урок 5
in в Python: мгновенная проверка принадлежности множеству
Один оператор, два механизма: in у множества отвечает мгновенно, у списка — перебором. Почему на миллионе элементов разница становится днями и секундами.
Множества · Урок 8
Разность и симметричная разность множеств в Python
Разность отвечает на вопрос «что есть у первого и чего нет у второго», симметричная — «что есть ровно у одного из двух». Операторы - и ^, методы difference и symmetric_difference и почему порядок множеств важен.
Множества · Урок 10
frozenset: неизменяемое множество в Python
Множество, которое нельзя менять: frozenset создаётся один раз, поддерживает все проверки и операции чтения и годится туда, куда set не пускают — ключом в словарь и элементом другого множества.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
Словари · Урок 7
in: проверка ключа в словаре
Оператор in отвечает на вопрос «есть ли такой ключ»: проверка перед доступом вместо KeyError, not in, грабли с проверкой значений и причина скорости поиска.
проверить есть ли ключ в словареоператор in python словарь
Строки · Урок 8
Поиск: find, rfind и in
Поиск в строке отвечает на три разных вопроса: «есть ли?», «где?» и «с чего начинается?». Разбираем in, find, rfind, startswith и endswith — и опасное значение -1, которое притворяется индексом.
оператор in pythonpython проверить наличие подстроки
Множества · Урок 6
Объединение множеств в Python: оператор | и union
Гости субботы плюс гости воскресенья — но каждый посчитан один раз. Оператор | и метод union собирают два множества в одно без дубликатов.
оператор | pythonpython объединить множества