Set в Python: первое множество и исчезающие дубликаты
Список терпит дубликаты, множество — нет: {1, 3, 3} хранит каждый элемент один раз. Первое множество, исчезающие повторы и честная печать через sorted.
Редакция Питоники
Списки хранят данные как записали: пять визитов — пять элементов, даже если приходил один и тот же человек. Для отчёта это часто не то, что нужно: статистику интересуют уникальные имена, а не количество повторов. Для таких задач в Python есть множество — set: коллекция, которая физически не может хранить дубликат. Уникальность в ней не написана руками, а встроена в саму структуру. Разберём, как создать первое множество, что происходит с повторами и почему множества печатают особым способом.
Старый способ: цикл с проверкой
До знакомства с множествами повторяемость убирали вручную: заводили пустой список и добавляли в него элемент, только если его там ещё нет. Такой приём встречается в чужом коде до сих пор, поэтому полезно узнать его в лицо:
seen = []
for name in ['анна', 'борис', 'анна', 'вера', 'анна']:
if name not in seen:
seen.append(name)
print(sorted(seen))
print('уникальных:', len(seen))
['анна', 'борис', 'вера'] уникальных: 3
Работает: три имени вместо пяти визитов. Но три строки кода, две структуры и проверка на каждом шаге — ради операции, которая должна быть одной. Множество делает то же самое при создании, без цикла и без проверок.
Первое множество: фигурные скобки
Множество создаётся функцией set от готовой коллекции — например, от списка визитов. Дубликаты она отбрасывает сама, а длину отдаёт знакомой len:
visits = ['анна', 'борис', 'анна', 'вера', 'анна']
guests = set(visits)
print('визитов:', len(visits))
print('гостей:', len(guests))
print(sorted(guests))
визитов: 5 гостей: 3 ['анна', 'борис', 'вера']
Пять визитов сжались в три гостя — set посчитал каждого человека один раз. Никаких условий и вспомогательных списков: уникальность — это свойство самой структуры, а не алгоритм поверх неё. Дальше по урокам мы увидим, что за это свойство платят порядком и изменяемыми элементами, но сначала — второй способ создания.
Дубликаты исчезают при создании
Множество записывают и литералом — элементами в фигурных скобках, через запятую. Что случится, если в записи продублировать значения:
numbers = {1, 3, 3, 5, 5, 5, 7}
print('в записи:', len(numbers))
print(sorted(numbers))
print('уникальных:', len(set([10, 20, 10, 30, 20])))
в записи: 4 [1, 3, 5, 7] уникальных: 3
Множество хранит каждый элемент ровно один раз: повтор при создании не ошибка, а просто лишний вход, который не пустили. Семёрка записей с дубликатами честно превратилась в четыре значения. Этот же приём — быстрый подсчёт уникальных: длина списка минус длина множества показывает, сколько раз данные повторялись.
orders = ['anna', 'boris', 'anna', 'vera', 'anna', 'boris']
unique = set(orders)
print('заказов:', len(orders))
print('клиентов:', len(unique))
print(sorted(unique))
заказов: 6 клиентов: 3 ['anna', 'boris', 'vera']
Шесть заказов, три клиента — одна строка вместо цикла из первого примера. Уникальность посчитана без единой проверки.
Скобки одни, типы разные
У списков и множеств разные скобки, но путаница живёт глубже: фигурные скобки в Python обслуживают сразу две структуры. Посмотрим на оба литерала рядом:
both = [1, 2, 3]
unique = {1, 2, 3}
print(type(both).__name__, type(unique).__name__)
print(len(both), len(unique))
list set 3 3
Квадратные скобки дают список, фигурные — множество. А вот фигурные скобки без элементов {} дают не пустое множество, а пустой словарь — это самая известная ловушка темы, и ей целиком посвящён следующий урок. Пока запомните: пустое множество создаётся только через set().
Порядок не гарантирован: печатаем через sorted
Список помнит порядок, в котором его записали. Множество — нет: оно устроено как хеш-таблица, и элементы лежат в ней так, как легли при вставке. Порядок внутри set может отличаться от записи и меняться между запусками и версиями Python, поэтому результат прямой печати сверить нельзя:
print({'б', 'а', 'в'})
Надёжный способ — функция sorted: она принимает любое перебираемое, в том числе множество, и возвращает обычный список в порядке возрастания. Список уже печатается предсказуемо, а заодно его можно срезать, посчитать и передать дальше:
letters = {'б', 'а', 'в'}
print(sorted(letters))
print(type(sorted(letters)))
print(len(letters))
['а', 'б', 'в'] <class 'list'> 3
sorted вернул список — на это указывает <class 'list'>. Само множество letters при этом не изменилось: sorted ничего не переставляет внутри источника, он лишь собирает его элементы в новый отсортированный список. Договоримся на весь курс: множества печатаем через sorted(s), len(s) или проверки True/False — никогда напрямую.
Что можно положить в множество
Элементом множества может быть неизменяемое значение: число, строка, кортеж. Изменяемые — списки и словари — не проходят: Python вычисляет для каждого элемента хеш, а у изменяемых объектов хеш не определён. Попытка положить список в множество падает с TypeError:
ok = {1, 2, 'три'}
print(len(ok))
try:
bad = {1, [2, 3]}
except TypeError as e:
print('Ошибка:', e)
print(sorted({1, 2}))
3 Ошибка: unhashable type: 'list' [1, 2]
Сообщение говорит прямо: unhashable type — изменяемый тип без хеша. Механизм хеша — тот же, что у ключей словаря: если вы клали ключи в dict, это ограничение вам уже знакомо, а в уроке про общие механизмы множеств и словарей мы сведём их вместе. Тройка, строка и пара чисел в одном множестве при этом живут спокойно — важна неизменяемость элемента, а не одинаковость типов.
Множество или список
Обе структуры хранят набор значений, но заточены под разное. Сводим выбор в таблицу:
| Задача | Инструмент | Почему |
|---|---|---|
| Уникальные элементы без дублей | set | Уникальность встроена: дубликаты исчезают сами |
| Порядок элементов важен | list | Список хранит порядок, множество — нет |
| Много проверок есть или нет | set | in у множества отвечает мгновенно (урок 5) |
| Пары ключ-значение | dict | Множество хранит только значения, без пар |
Первое множество создано, и два главных свойства на руках: уникальность и мгновенная проверка принадлежности — ей посвящён урок про оператор in. А пока наведём порядок в способах создания: литерал, set() от списка, set() от строки и коварные пустые скобки — всё это в уроке про создание множеств.
Сначала предскажи ответ в голове — это главный навык программиста.
tags = {'a', 'b', 'a', 'c'}
print(len(tags))
print(sorted(tags))
words = ['раз', 'два', 'раз', 'три']
unique = set(words)
print(len(words) - len(unique))
s = {5, 3, 3, 9}
print(type(s).__name__, len(s))
1. Что произойдёт с дубликатами при создании множества {3, 3, 5}?
2. Как надёжно напечатать множество по возрастанию?
3. Что вернёт len({1, 2, 2, 3, 3})?
4. Какой тип у литерала {} без элементов?
5. Почему список нельзя сделать элементом множества?
6. Что вернёт set(visits), если в списке visits пять визитов и три имени?
Дан список визитов views = ['vk', 'tg', 'vk', 'ok', 'tg', 'vk']. Соберите уникальные источники во множество sources и напечатайте три строки: визитов N, уникальных M и отсортированный список источников.
Что такое set в Python простыми словами?
Множество — коллекция, которая хранит каждый элемент ровно один раз: {1, 3, 3} превращается в множество из двух значений. Оно не помнит порядок элементов, зато умеет отвечать на вопрос есть ли элемент мгновенно. Создаётся литералом в фигурных скобках или функцией set() от списка и строки.
Урок 2: создание множествКак напечатать множество в Python?
Через sorted(s): функция вернёт обычный список элементов по возрастанию, и печать будет предсказуемой. Прямой print(s) печатает множество в непредсказуемом порядке — такой вывод нельзя сверить и нельзя положить в отчёт. Для проверки размера используйте len(s).
Чем set отличается от list?
Список хранит порядок и дубликаты, множество хранит уникальность без порядка. Список допускает индексы и срезы, у множества их нет. Зато проверка in у множества мгновенна даже на миллионах элементов, а у списка она перебирает значения по очереди.
Урок 5: мгновенная проверка inПочему {} — это не пустое множество?
Фигурные скобки в Python обслуживают две структуры, и без элементов они отданы словарю: type({}) вернёт dict. Пустое множество создаётся только функцией set() — это самая частая ловушка темы.
Урок 2: {} и set()Какие элементы можно хранить в множестве?
Неизменяемые значения: числа, строки, кортежи. Изменяемые — списки и словари — не проходят: множество вычисляет хеш элемента, а у изменяемых объектов хеша нет, поэтому попытка падает с TypeError: unhashable type: 'list'.
Понравился урок? Сошлитесь на него
«Множество хранит каждый элемент ровно один раз: повтор при создании не ошибка, а просто лишний вход, который не пустили.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что дальше
Осталось в разделе: 20 из 20. Прогресс хранится в вашем браузере.
Что читать дальше
Множества · Урок 2
Создание множеств: {} и set() — литерал, список, строка
Два способа создать множество: литерал в фигурных скобках и set() от списка или строки. Пустые скобки — это словарь, поэтому пустое множество пишут set().
Множества · Урок 5
in в Python: мгновенная проверка принадлежности множеству
Один оператор, два механизма: in у множества отвечает мгновенно, у списка — перебором. Почему на миллионе элементов разница становится днями и секундами.
Словари · Урок 1
Словарь в Python: ключ и значение
Словарь — структура «ключ — значение»: достаём номер телефона по имени из телефонной книги, сравниваем dict со списком на живых данных и заглядываем под капот — как Python находит значение по ключу.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
Pandas · Урок 6
Сортировка, топы и подсчёты: sort_values, value_counts, rank
sort_values по нескольким столбцам, nlargest вместо сортировки всей таблицы, частоты value_counts и рейтинги rank — собираем отчёты «топ-10 товаров» и «доли городов».
value_counts pandas посчитать уникальные значенияpandas для начинающих
Matplotlib / Seaborn · Урок 1
Визуализация данных в Python: первое знакомство с Matplotlib
Первый график в Python за три строки кода, анатомия figure и axes, шпаргалка «какой график для каких данных» и сохранение в PNG. Всё запускается прямо на странице.
matplotlib для начинающихmatplotlib уроки для начинающих
Множества · Урок 16
Как удалить дубликаты из списка в Python одной строкой
Убрать повторы из списка — две строки: set(x) выкидывает дубликаты, dict.fromkeys(x) сохраняет порядок первого вхождения. Разбираем оба приёма и случай, когда множеству нужен ваш ключ.
python удалить дубликатыpython убрать повторяющиеся элементы из списка