Перейти к содержимому
Editor

Множества в Python: уникальные элементы, операции и применение

Средний20 min6 упр.85 XP

Этот урок переведён с английского оригинала.Read in EnglishLeer en españolСообщить об ошибке в переводе

0/6 упр.

Представьте, что вы учитель и отмечаете присутствующих. Ученик случайно расписался в листе посещаемости дважды. Значит ли это, что он на уроке дважды? Конечно, нет. Вам важно только, кто пришёл, а не сколько раз он написал своё имя.

Множество в Python работает так же. Это коллекция, которая автоматически удаляет дубликаты. Каждый элемент множества уникален. Порядок множествам тоже неважен: их интересует только принадлежность, то есть есть элемент в множестве или нет.

В этом уроке вы научитесь создавать множества, выполнять мощные операции вроде объединения и пересечения, изменять множества с помощью методов и узнаете, в каких задачах множества подходят лучше всего.

Как создать множество в Python

Множество создают, перечисляя элементы через запятую внутри фигурных скобок {}. Если добавить повторяющиеся значения, Python молча их проигнорирует.

Создание множеств с помощью фигурных скобок
# A basic set of fruits
fruits = {'apple', 'banana', 'cherry'}
print(fruits)
# Duplicates are automatically removed
colors = {'red', 'blue', 'red', 'green', 'blue'}
print(colors) # Only 3 unique colors
Вывод
{'apple', 'banana', 'cherry'}
{'red', 'green', 'blue'}

Обратите внимание: порядок в выводе может отличаться от того, в котором вы записали элементы. Множество является неупорядоченной коллекцией, поэтому Python может хранить элементы внутри в любом порядке. Не рассчитывайте, что множество сохранит определённый порядок.

Множество можно создать и из списка с помощью конструктора set(). Это популярный способ удалить дубликаты из списка.

Создание множеств с помощью конструктора set()
# Convert a list with duplicates into a set
names_list = ['Alice', 'Bob', 'Alice', 'Charlie', 'Bob']
names_set = set(names_list)
print(names_set) # Only unique names
# Create a set from a string (each character becomes an item)
letters = set('hello')
print(letters) # {'h', 'e', 'l', 'o'} - only one 'l'
Вывод
{'Bob', 'Alice', 'Charlie'}
{'o', 'l', 'e', 'h'}

Операции над множествами: объединение, пересечение и разность

Настоящая сила множеств в операциях над множествами. С их помощью множества можно объединять, сравнивать и находить различия между ними. Представляйте их как диаграммы Венна (или круги Эйлера) из школьной математики.

Объединение: всё вместе

Объединение даёт все элементы обоих множеств без дубликатов. Используйте оператор | или метод .union().

Объединение собирает все уникальные элементы
math_students = {'Alice', 'Bob', 'Charlie'}
science_students = {'Bob', 'Diana', 'Charlie'}
# Union - everyone in either class
all_students = math_students | science_students
print(all_students)
# Same thing using the method
all_students = math_students.union(science_students)
print(all_students)
Вывод
{'Charlie', 'Bob', 'Alice', 'Diana'}
{'Charlie', 'Bob', 'Alice', 'Diana'}

Пересечение: что общего

Пересечение даёт только те элементы, которые есть в обоих множествах. Используйте оператор & или .intersection().

Пересечение находит общие элементы
math_students = {'Alice', 'Bob', 'Charlie'}
science_students = {'Bob', 'Diana', 'Charlie'}
# Intersection - students in BOTH classes
both_classes = math_students & science_students
print(both_classes) # {'Bob', 'Charlie'}
Вывод
{'Bob', 'Charlie'}

Разность: что есть только в одном множестве

Разность даёт элементы, которые есть в первом множестве, но отсутствуют во втором. Используйте оператор - или .difference(). Здесь порядок имеет значение.

Разность находит элементы, которые есть только в одном множестве
math_students = {'Alice', 'Bob', 'Charlie'}
science_students = {'Bob', 'Diana', 'Charlie'}
# Who is ONLY in math?
math_only = math_students - science_students
print(math_only) # {'Alice'}
# Who is ONLY in science?
science_only = science_students - math_students
print(science_only) # {'Diana'}
Вывод
{'Alice'}
{'Diana'}

Симметрическая разность: элементы только одного из множеств

Симметрическая разность даёт элементы, которые есть в одном из множеств, но не в обоих сразу. Её можно считать противоположностью пересечения. Используйте оператор ^ или .symmetric_difference().

Симметрическая разность исключает общие элементы
math_students = {'Alice', 'Bob', 'Charlie'}
science_students = {'Bob', 'Diana', 'Charlie'}
# Students in only ONE class (not both)
exclusive = math_students ^ science_students
print(exclusive) # {'Alice', 'Diana'}
Вывод
{'Alice', 'Diana'}

Как добавлять и удалять элементы множества

Множества изменяемы: после создания в них можно добавлять элементы и удалять их. Вот основные методы, которые вам понадобятся.

Добавление и удаление элементов множества
fruits = {'apple', 'banana'}
# Add a single item
fruits.add('cherry')
print(fruits)
# Add multiple items at once
fruits.update(['date', 'elderberry'])
print(fruits)
# Remove an item (raises error if not found)
fruits.remove('banana')
print(fruits)
# Discard an item (no error if not found)
fruits.discard('mango') # No crash!
print(fruits)
Вывод
{'apple', 'banana', 'cherry'}
{'date', 'elderberry', 'apple', 'banana', 'cherry'}
{'date', 'elderberry', 'apple', 'cherry'}
{'date', 'elderberry', 'apple', 'cherry'}

Ещё можно удалить из множества все элементы или извлечь из него произвольный элемент.

Методы pop() и clear()
numbers = {10, 20, 30, 40, 50}
# Pop removes and returns an arbitrary item
removed = numbers.pop()
print(f'Removed: {removed}')
print(f'Remaining: {numbers}')
# Clear removes everything
numbers.clear()
print(numbers) # set()
Вывод
Removed: 50
Remaining: {20, 40, 10, 30}
set()

Почему множества молниеносно проверяют принадлежность

Одна из главных причин использовать множество: проверка, есть ли в нём элемент. Ключевое слово in работает и со списками, и со множествами, но множества справляются с этим намного быстрее.

Быстрая проверка принадлежности с помощью in
allowed_users = {'alice', 'bob', 'charlie', 'diana'}
user = 'bob'
if user in allowed_users:
print(f'{user} is allowed!')
else:
print(f'{user} is not allowed.')
# Checking who is NOT in the set
user2 = 'eve'
if user2 not in allowed_users:
print(f'{user2} is not on the list.')
Вывод
bob is allowed!
eve is not on the list.

Что такое frozenset?

Frozenset (замороженное множество) представляет собой неизменяемую версию множества. После создания в него нельзя добавлять элементы и удалять их из него. Благодаря этому frozenset хешируемый, то есть его можно использовать как ключ словаря или хранить внутри других множеств.

frozenset: неизменяемые множества
# Create a frozenset
vowels = frozenset(['a', 'e', 'i', 'o', 'u'])
print(vowels)
# You can still do set operations
consonants = frozenset(['b', 'c', 'd', 'f', 'g'])
all_letters = vowels | consonants
print(all_letters)
# But you CANNOT modify it
# vowels.add('y') # AttributeError!
Вывод
frozenset({'u', 'o', 'i', 'e', 'a'})
frozenset({'u', 'o', 'i', 'f', 'g', 'd', 'e', 'b', 'c', 'a'})

Когда использовать множество вместо списка?

Множества и списки решают разные задачи. Простое правило: если вам важен порядок или нужны повторы, используйте список. Если важны уникальность или быстрый поиск, используйте множество.

Используйте список, когда...
# Order matters
playlist = ['song1', 'song2', 'song3']

# Duplicates are meaningful
die_rolls = [3, 5, 3, 2, 5, 6]

# You need index access
first = playlist[0]
Используйте множество, когда...
# Only unique items matter
tags = {'python', 'coding', 'tutorial'}

# Fast membership checks
if 'python' in tags:
    print('Found!')

# Removing duplicates
unique = set([1, 2, 2, 3, 3])

Практические упражнения

Удалите дубликаты из списка
Напишите код

У вас есть список адресов электронной почты, и некоторые из них повторяются. Создайте множество unique_emails из списка emails и выведите его, отсортировав по алфавиту с помощью sorted().

emails = ['alice@mail.com', 'bob@mail.com', 'alice@mail.com', 'charlie@mail.com', 'bob@mail.com']
# Create a set of unique emails and print them sorted
Предскажите вывод с множеством
Угадайте вывод

Что выведет этот код? Хорошо подумайте о том, как множества обрабатывают дубликаты и что возвращает функция len().

data = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique = set(data)
print(len(unique))

Напишите инструкцию print(), которая выводит точно такой же результат.

# What does this code print?
data = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique = set(data)
print(len(unique))
Найдите учеников, которые ходят на оба предмета
Напишите код

У вас есть два множества: math и english. Найдите и выведите учеников, которые записаны на оба предмета. Выведите результат в виде отсортированного списка.

math = {'Alice', 'Bob', 'Charlie', 'Diana'}
english = {'Bob', 'Diana', 'Eve', 'Frank'}
# Find students in both classes and print sorted
Исправьте ошибку с пустым множеством
Исправьте ошибку

Этот код пытается создать пустое множество, добавить в него элементы и вывести результат. Но в нём ошибка: программист создал пустое множество с помощью {}. Исправьте ошибку, чтобы код работал правильно.

# Bug: this creates a dictionary, not a set!
my_set = {}
my_set.add('python')
my_set.add('java')
my_set.add('python') # duplicate
print(sorted(my_set))
Найдите недостающие продукты
Напишите код

У вас есть множество recipe со всеми нужными ингредиентами и множество pantry с тем, что уже лежит у вас в кладовой. Найдите ингредиенты, которые ещё нужно купить, и выведите их в виде отсортированного списка.

recipe = {'flour', 'sugar', 'eggs', 'butter', 'vanilla'}
pantry = {'flour', 'eggs', 'salt', 'pepper'}
# Find and print what you need to buy (sorted)
Удалите дубликаты, сохранив порядок
Напишите код

Напишите функцию dedupe(items), которая удаляет дубликаты из списка и сохраняет исходный порядок элементов. Используйте множество, чтобы отслеживать уже встреченные элементы. Верните список без дубликатов.

Проверьте её вызовом print(dedupe([3, 1, 4, 1, 5, 9, 2, 6, 5, 3])).

def dedupe(items):
# Use a set to track seen items
# Build a new list with only first occurrences
pass
print(dedupe([3, 1, 4, 1, 5, 9, 2, 6, 5, 3]))

Похожие уроки

Урок был полезен?