Создание множества
Множество — неупорядоченная коллекция уникальных элементов:
# Через фигурные скобки
fruits = {"яблоко", "банан", "вишня"}
# Через функцию set() — можно передать любой итерируемый объект (например, список)
numbers = set([1, 2, 2, 3, 3, 3]) # {1, 2, 3}
# Пустое множество (не {} — это словарь!)
empty = set()
Операции над множествами
Математические операции:
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a | b) # {1, 2, 3, 4, 5, 6} — объединение
print(a & b) # {3, 4} — пересечение
print(a - b) # {1, 2} — разность
print(a ^ b) # {1, 2, 5, 6} — симметрическая разность
Наглядно увидеть, какие элементы попадают в результат каждой операции, можно на диаграмме Эйлера. Нажмите кнопку под диаграммой — нужные числа подсветятся:
Методы множеств
Основные методы. Код выполняется последовательно — комментарии показывают множество после каждой строки:
s = {1, 2, 3}
print(3 in s) # True — оператор in проверяет вхождение
print(10 not in s) # True — not in: элемента нет во множестве
s.add(4) # {1, 2, 3, 4} — добавить элемент
s.remove(2) # {1, 3, 4} — KeyError, если элемента нет
s.discard(10) # {1, 3, 4} — ошибки не будет, даже если элемента нет
s.pop() # удаляет и возвращает произвольный элемент
s.clear() # set() — очищает множество
Метод .remove(x) вызывает ошибку KeyError, если элемента x нет во множестве:
s = {1, 2, 3}
s.remove(10) # KeyError: 10
Почему элементы должны быть хешируемыми
Перед добавлением элемента Python вычисляет его хеш — число, которое возвращает встроенная функция hash():
print(hash(42)) # 42 — у чисел хеш совпадает с самим числом
print(hash("hello")) # некоторое число — при каждом запуске своё!
Хеш определяет ячейку таблицы, в которую попадёт элемент. Отсюда три следствия:
- Проверка
x in sне перебирает элементы по очереди, а сразу смотрит в нужную ячейку по хешу — поэтому работает быстро даже на больших множествах. - Порядок элементов определяется их хешами, а не порядком добавления — поэтому множество «неупорядочено».
- Изменяемые объекты (списки, словари) добавить нельзя: при изменении объекта изменился бы и его хеш, и элемент «потерялся» бы в таблице. Неизменяемые — числа, строки и кортежи — подходят:
data = {1, "hello", (2, 3)}
data.add([4, 5]) # TypeError: unhashable type: 'list'