Множества в Python
Множество (set) в Python решает две конкретные задачи: быстрая проверка членства (есть ли элемент в коллекции) и хранение только уникальных значений без дубликатов. Это неупорядоченная коллекция, основанная на математической концепции множества.
Что такое множество?
Множество в Python — это неупорядоченная коллекция уникальных элементов. Два ключевых свойства множеств:
- Неупорядоченность: элементы не имеют определённого порядка и не индексируются — обратиться к «третьему элементу множества» нельзя, можно только перебрать все элементы или проверить, есть ли в нём конкретный
- Уникальность: каждый элемент встречается только один раз
Основные характеристики множеств:
- Изменяемость: можно добавлять и удалять элементы
- Неизменяемые элементы: внутрь множества можно положить только неизменяемые объекты (числа, строки, кортежи)
- Эффективность: оптимизированы для быстрой проверки вхождения элементов
Поскольку множества основаны на математической концепции, у них есть операции объединения, пересечения и разности.
Создание множеств
С помощью фигурных скобок
Python 3.13# Множество целых чисел numbers = {1, 2, 3, 4, 5} print(numbers){1, 2, 3, 4, 5}# Автоматическое удаление дубликатов duplicates = {1, 2, 2, 3, 3, 3, 4, 5, 5} print(duplicates){1, 2, 3, 4, 5}# В одном множестве могут лежать разные неизменяемые типы mixed = {1, "привет", (1, 2, 3)} print(len(mixed)) # число, строка и кортеж — все три поместились3
С помощью конструктора set()
Python 3.13# Пустое множество empty_set = set() print(empty_set)set()# Создание множества из списка numbers_set = set([1, 2, 2, 3, 4, 4, 5]) print(numbers_set){1, 2, 3, 4, 5}# Создание множества из строки — повторяющиеся буквы схлопываются letters = set("hello") print(len(letters)) # в "hello" две 'l', в множестве осталась одна — всего 4 буквы4
Основные операции с множествами
Проверка наличия элемента
Python 3.13fruits = {"яблоко", "банан", "вишня"} print("яблоко" in fruits)Trueprint("груша" in fruits)False
Добавление и удаление элементов
Порядок элементов в множестве произвольный, поэтому в примерах со строками ниже мы выводим их через sorted(): эта функция возвращает отсортированный список, и вывод не скачет от запуска к запуску.
Python 3.13fruits = {"яблоко", "банан"} # Добавление одного элемента fruits.add("вишня") print(sorted(fruits))['банан', 'вишня', 'яблоко']# Добавление нескольких элементов fruits.update(["груша", "апельсин"]) print(sorted(fruits))['апельсин', 'банан', 'вишня', 'груша', 'яблоко']# Удаление элемента fruits.remove("банан") # вызывает KeyError, если элемента нет print(sorted(fruits))['апельсин', 'вишня', 'груша', 'яблоко']# Безопасное удаление элемента fruits.discard("вишня") # не вызывает ошибку, если элемента нет print(sorted(fruits))['апельсин', 'груша', 'яблоко']# pop() убирает и возвращает какой-то элемент — какой именно, заранее неизвестно removed = fruits.pop() print(len(fruits)) # осталось на один меньше2# Очистка множества fruits.clear() print(fruits)set()
Перебор множества
Множество перебирают циклом for. Порядок при этом произвольный и может меняться от запуска к запуску — это и значит «неупорядоченное». Когда нужен предсказуемый порядок, сортируем через sorted():
Python 3.13colors = {"красный", "синий", "зеленый"} for color in sorted(colors): print(color)зеленый красный синий
Математические операции над множествами
Три основные операции — объединение, пересечение и разность. Удобно визуализировать их диаграммами Венна:

Объединение (Union)
Все элементы из обоих множеств:
Python 3.13a = {1, 2, 3} b = {3, 4, 5} union_set = a | b print(union_set){1, 2, 3, 4, 5}
То же самое можно написать как a.union(b).
Пересечение (Intersection)
Элементы, которые есть в обоих множествах:
Python 3.13a = {1, 2, 3, 4} b = {3, 4, 5, 6} intersection_set = a & b print(intersection_set){3, 4}
То же самое можно написать как a.intersection(b).
Разность (Difference)
Элементы первого множества, которых нет во втором:
Python 3.13a = {1, 2, 3, 4} b = {3, 4, 5, 6} difference_set = a - b print(difference_set){1, 2}
То же самое можно написать как a.difference(b).
Операции сравнения множеств
Python 3.13a = {1, 2, 3} b = {1, 2, 3, 4, 5} c = {1, 2, 3} # Равенство множеств print(a == c) # Содержат одинаковые элементыTrue# Подмножества print(a.issubset(b)) # Все элементы a есть в bTrueprint(a < b) # a является строгим подмножеством bTrue# Надмножества print(b.issuperset(a)) # b содержит все элементы aTrueprint(b > a) # b является строгим надмножеством aTrue# Проверка на отсутствие общих элементов d = {6, 7, 8} print(a.isdisjoint(d)) # Нет общих элементовTrue
Неизменяемые множества (frozenset)
Если нужен неизменяемый вариант множества, используйте frozenset:
Python 3.13# Создание frozenset immutable_set = frozenset([1, 2, 3, 4]) print(immutable_set)frozenset({1, 2, 3, 4})# Попытка изменить frozenset вызывает ошибку try: immutable_set.add(5) except AttributeError as e: print(f"Ошибка: {e}")Ошибка: 'frozenset' object has no attribute 'add'# frozenset можно использовать как ключ словаря или элемент другого множества normal_set = {frozenset([1, 2]), frozenset([3, 4])} print(len(normal_set)) # два frozenset'а поместились внутрь2
Практические примеры использования множеств
1. Удаление дубликатов из списка
Python 3.13numbers = [1, 2, 2, 3, 3, 3, 4, 5, 5] unique_numbers = list(set(numbers)) print(unique_numbers)[1, 2, 3, 4, 5]
2. Нахождение общих элементов
Python 3.13users_group1 = ["Анна", "Иван", "Мария", "Петр", "Елена"] users_group2 = ["Иван", "Ольга", "Елена", "Алексей"] # Общие элементы (пересечение) common_users = set(users_group1) & set(users_group2) print(f"Пользователи в обеих группах: {sorted(common_users)}")Пользователи в обеих группах: ['Елена', 'Иван']# Элементы только из первой группы (разность) only_group1 = set(users_group1) - set(users_group2) print(f"Только в группе 1: {sorted(only_group1)}")Только в группе 1: ['Анна', 'Мария', 'Петр']# Все уникальные элементы (объединение) all_users = set(users_group1) | set(users_group2) print(f"Все уникальные пользователи: {sorted(all_users)}")Все уникальные пользователи: ['Алексей', 'Анна', 'Елена', 'Иван', 'Мария', 'Ольга', 'Петр']
3. Проверка уникальности элементов
Python 3.13def are_all_unique(items): """Проверяет, все ли элементы в последовательности уникальны.""" return len(set(items)) == len(items) print(are_all_unique([1, 2, 3, 4, 5]))Trueprint(are_all_unique([1, 2, 3, 3, 4]))False
Ограничения и производительность
Ограничения
Элементы множества должны быть хешируемыми (неизменяемыми):
Python 3.13# Работает с неизменяемыми типами данных valid_set = {1, "hello", (1, 2, 3)} print(len(valid_set)) # число, строка и кортеж хешируемы — все три поместились3# Ошибка с изменяемыми типами данных try: invalid_set = {1, [2, 3], {"a": 1}} except TypeError as e: print(f"Ошибка: {e}")Ошибка: unhashable type: 'list'
Можно добавлять:
- Числа (int, float, complex)
- Строки (str)
- Кортежи (tuple) с хешируемыми элементами
- Frozenset
Нельзя добавлять:
- Списки (list)
- Словари (dict)
- Множества (set)
Производительность
Ради быстрого поиска множества и придуманы. Проверим на миллионе чисел: ищем последнее — то есть худший случай для списка, который вынужден просмотреть всё подряд.
Python 3.13import time data = list(range(1_000_000)) data_set = set(data) start = time.time() for _ in range(100): 999_999 in data list_time = time.time() - start start = time.time() for _ in range(100): 999_999 in data_set set_time = time.time() - start print(f"Поиск в списке: {list_time:.3f} сек")Поиск в списке: 0.442 секprint(f"Поиск в множестве: {set_time:.5f} сек")Поиск в множестве: 0.00001 сек
Конкретные числа у вас получатся свои — они зависят от машины и загруженности, — но разрыв никуда не денется: десятки тысяч раз. Списку приходится перебирать элементы по одному, пока не найдёт нужный. Множество вместо перебора сразу вычисляет, где значение должно лежать, и проверяет только это место — и делает это одинаково быстро хоть на десяти элементах, хоть на миллионе.
Операции со сложностью O(1) (константное время):
- Проверка наличия элемента: x in set
- Добавление элемента: set.add(x)
- Удаление элемента: set.remove(x), set.discard(x)
Проверка понимания
Что выведет print(set([1, 2, 2, 3, 3, 3]))?
