Множества и операции над ними
Множества и операции над ними
Списки хранят последовательности с дубликатами. Словари хранят пары ключ-значение. А что, если нужна коллекция уникальных значений, без порядка и ключей? Для этого Python предлагает множество (set).
Что такое множество
Множество — неупорядоченная коллекция уникальных элементов. Дубликаты автоматически удаляются. Синтаксис — фигурные скобки:
fruits = {"яблоко", "банан", "вишня", "банан"} # банан дважды
print(fruits) # {'вишня', 'яблоко', 'банан'} — только 3 элемента
print(type(fruits)) # <class 'set'>
Порядок элементов не гарантирован — каждый запуск может давать разный вывод.
Важно: {} — это пустой словарь, не множество! Для пустого множества — set():
empty_set = set() # правильно
empty_dict = {} # это словарь!
Создание множества
# Из литерала:
nums = {1, 2, 3, 4, 5}
# Из итерируемого через set():
from_list = set([1, 2, 2, 3, 3, 3]) # {1, 2, 3}
from_string = set("hello") # {'h', 'e', 'l', 'o'} — уникальные символы
from_range = set(range(5)) # {0, 1, 2, 3, 4}
Элементы множества
Элементы должны быть неизменяемыми (hashable): числа, строки, кортежи. Списки и словари не могут быть элементами множества.
Основные операции
s = {1, 2, 3, 4, 5}
# Добавить элемент:
s.add(6)
print(s) # {1, 2, 3, 4, 5, 6}
# Удалить элемент (KeyError если нет):
s.remove(6)
# Удалить без ошибки:
s.discard(99) # нет 99 — тихо игнорирует
# Проверка вхождения (O(1) — быстро!):
print(3 in s) # True
print(9 in s) # False
# Длина:
print(len(s)) # 5
Теоретико-множественные операции
Это главная сила set — операции из теории множеств:
a = {1, 2, 3, 4, 5}
b = {3, 4, 5, 6, 7}
Объединение (union): все элементы из обоих множеств:
print(a | b) # {1, 2, 3, 4, 5, 6, 7}
print(a.union(b)) # то же самое
Пересечение (intersection): только общие элементы:
print(a & b) # {3, 4, 5}
print(a.intersection(b)) # то же
Разность (difference): элементы a, которых нет в b:
print(a - b) # {1, 2}
print(a.difference(b)) # то же
print(b - a) # {6, 7}
Симметричная разность: элементы, которые есть только в одном из двух:
print(a ^ b) # {1, 2, 6, 7}
print(a.symmetric_difference(b)) # то же
Подмножество и надмножество
small = {3, 4}
big = {1, 2, 3, 4, 5}
print(small.issubset(big)) # True — small ⊆ big
print(big.issuperset(small)) # True — big ⊇ small
print(small <= big) # True — оператор подмножества
print(big >= small) # True
Практические применения
Удаление дубликатов из списка:
numbers = [1, 2, 3, 2, 1, 4, 3, 5]
unique = list(set(numbers))
print(unique) # [1, 2, 3, 4, 5] — порядок может измениться!
Проверка пересечения:
required = {"python", "sql", "git"}
candidate = {"python", "java", "git", "docker"}
common = required & candidate
missing = required - candidate
print(f"Есть: {common}") # {'python', 'git'}
print(f"Нет: {missing}") # {'sql'}
Неизменяемое множество: frozenset
frozenset — неизменяемая версия set. Можно использовать как ключ словаря:
fs = frozenset({1, 2, 3})
d = {fs: "frozen value"}
Проверь себя
Что выведет следующий код?
a = {1, 2, 3}
b = {2, 3, 4}
print(a & b)
print(a | b)
print(a - b)
a & b→{2, 3}(пересечение)a | b→{1, 2, 3, 4}(объединение)a - b→{1}(в a, но не в b)
Итог
set— неупорядоченная коллекция уникальных элементов;{}— словарь,set()— множество.add()добавляет,remove()удаляет (KeyError если нет),discard()удаляет тихо.inдля множества работает за O(1) — намного быстрее, чем для списка.- Операции:
|(объединение),&(пересечение),-(разность),^(симм. разность). - Типичные применения: удаление дубликатов, проверка вхождения, работа с уникальными наборами.
В следующем уроке сравним все три коллекции и решим, когда что использовать.