Практические задачи на множества Python и их решения

Раздел: Python -> Учебные задачи

Задачи на множества в Python

Как получить из списка только уникальные элементы?

Самый короткий способ — преобразовать список во множество, а затем обратно в список. Множество хранит только уникальные элементы, поэтому дубликаты автоматически удаляются.

numbers = [1, 2, 2, 3, 4, 3, 5]
unique = list(set(numbers))
print(unique)  # Результат: [1, 2, 3, 4, 5] (порядок может отличаться)

алгоритм решения задачи python (алгоритм решения задачи на python)

Этот подход работает как с числами, так и с любыми хэшируемыми объектами (строки, кортежи). Недостаток — потеря исходного порядка элементов.

Типичная ошибка:

Попытка использовать set() с нехэшируемыми элементами, например, списками внутри списка. Возникает TypeError: unhashable type: 'list'. Решение — преобразовать вложенные списки в кортежи перед созданием множества.

# Ошибка
data = [[1,2], [1,2], [3,4]]
# set(data) -> TypeError

# Исправление
data_tuples = [tuple(lst) for lst in data]
unique_tuples = list(set(data_tuples))

базовые задачи python (базовые задачи python)

Как удалить дубликаты, сохранив порядок элементов?

В Python 3.7+ словари сохраняют порядок вставки. Использование dict.fromkeys() даёт список уникальных элементов в порядке их первого появления.

numbers = [3, 1, 2, 1, 3, 4]
unique_ordered = list(dict.fromkeys(numbers))
print(unique_ordered)  # [3, 1, 2, 4]

задачи для обучения python (задачи для обучения python)

Для версий Python ниже 3.7 подойдёт collections.OrderedDict.

Как найти элементы, присутствующие в обоих списках?

Операция пересечения множеств (&) возвращает общие элементы. Это эффективно (сложность O(len(min(a,b)) в среднем) и лаконично.

a = [1, 2, 3, 4]
b = [3, 4, 5, 6]
common = list(set(a) & set(b))
print(common)  # [3, 4]

задачи на классы в python (задачи на классы в python)

Частая ошибка:

Забывают преобразовать списки в множества. Если применить & к спискам, получится ошибка TypeError: unsupported operand type(s) for &: 'list' and 'list'.

Как найти общие элементы без преобразования в множество?

Можно использовать list comprehension с проверкой in. Этот вариант медленнее (O(n*m)), но не требует хэшируемых элементов.

a = [1, 2, 'a', 3]
b = [3, 'a', 4]
common = [item for item in a if item in b]
print(common)  # ['a', 3]

множество python задачи (задачи на множества в python)

Если в исходных списках есть повторы, то в результате также появятся дубликаты. Для получения уникального множества общих элементов поверх результата можно применить set().

Как проверить, есть ли хотя бы один общий элемент у двух списков?

Метод isdisjoint() возвращает True, если множества не пересекаются. Соответственно, пересечение существует, если not set_a.isdisjoint(set_b).

set_a = {1, 2, 3}
set_b = {3, 4, 5}
print(not set_a.isdisjoint(set_b))  # True

задачи на модули python (задачи на модули в python)

Метод работает быстрее, чем построение пересечения, так как останавливается при нахождении первого общего элемента.

Как проверить пересечение без метода isdisjoint?

Вычислить длину пересечения: len(set_a & set_b) > 0. Этот вариант тоже рабочий, но менее эффективный при больших множествах.

set_a = {1, 2, 3}
set_b = {3, 4, 5}
print(len(set_a & set_b) > 0)  # True

задачи на операторы в python (задачи на операторы в python)

Как найти элементы, которые есть в первом списке, но отсутствуют во втором?

Разность множеств (оператор -) возвращает элементы первого множества, не входящие во второе.

a = [1, 2, 3, 4]
b = [3, 4, 5]
diff = list(set(a) - set(b))
print(diff)  # [1, 2]

задачи на последовательности python (задачи на последовательности в python)

Если нужно наоборот (элементы второго без первого), используйте set(b) - set(a).

Ошибка:

Применение - к спискам даёт TypeError. Всегда преобразуйте списки в множества.

Как получить разность списков, сохранив порядок исходного списка?

Через list comprehension с проверкой на отсутствие во множестве второго списка. Порядок сохраняется, дубликаты из первого списка тоже остаются (если не обрабатывать дополнительно).

a = [1, 2, 2, 3, 4]
b = [3, 4]
set_b = set(b)
diff_ordered = [item for item in a if item not in set_b]
print(diff_ordered)  # [1, 2, 2]

задачи на списки python (задачи на списки в python)

Использование множества для проверки not in даёт среднюю сложность O(len(a)), так как in для множества работает за O(1).

Как найти элементы, встречающиеся только в одном из двух множеств (симметрическая разность)?

Оператор ^ или метод symmetric_difference() возвращает элементы, принадлежащие ровно одному из двух множеств.

a = {1, 2, 3}
b = {3, 4, 5}
sym_diff = a ^ b
print(sym_diff)  # {1, 2, 4, 5}

пробелы python задача (задача на пробелы в строке python)

Это эквивалентно (a - b) | (b - a).

Как проверить, что одно множество является подмножеством другого?

Оператор <= или метод issubset(). Если все элементы первого множества содержатся во втором, возвращается True.

a = {1, 2}
b = {1, 2, 3}
print(a <= b)  # True
print(a.issubset(b))  # True

задачи на if else python (задачи на условные операторы if-else в python)

Типичная путаница:

Метод issuperset() делает обратную проверку: b.issuperset(a) равнозначно a <= b. Перепутав, можно получить неожиданный результат.

Как получить уникальные слова из строки?

Разделить строку на слова (обычно с помощью split()), привести к нижнему регистру для регистронезависимости и поместить в множество.

text = "Python is great and Python is easy"
words = set(text.lower().split())
print(words)  # {'python', 'great', 'and', 'is', 'easy'}

задачи на работу с файлами python (задачи на работу с файлами в python)

Для удаления знаков препинания можно использовать регулярные выражения.

Как отфильтровать элементы списка, оставив только входящие в заданное множество?

Используя list comprehension и проверку in на множестве. Множество обеспечивает быстрый поиск.

allowed = {'read', 'write', 'execute'}
actions = ['read', 'delete', 'write', 'rename']
filtered = [action for action in actions if action in allowed]
print(filtered)  # ['read', 'write']

задачи на функции в python (задачи на функции в python)

Как проверить, являются ли два слова анаграммами (с помощью множеств)?

Простая проверка через множества: set(word1) == set(word2). Однако этот способ не учитывает количество одинаковых букв. Для настоящих анаграмм лучше использовать collections.Counter. Множества подходят только для случая, когда каждая буква встречается не более одного раза.

# Подходит только для слов без повторяющихся букв
print(set('listen') == set('silent'))  # True
print(set('aabc') == set('abcc'))     # True (ошибочно, т.к. разные количества)

Предостережение:

При использовании множеств теряется информация о кратности элементов. Для корректной проверки анаграмм применяйте sorted(word1) == sorted(word2) или Counter.

- Python 3 произведение чисел (произведение чисел в python 3)
- напиши условие задачи python (написание условия задачи на python)
- объяснения python задача (объяснение задачи на python)

Дополнительные примеры работы с множествами

Примеры ниже расширяют базовые операции и показывают неочевидные сценарии использования множеств.

Как найти уникальные комбинации элементов из нескольких списков?

Множества кортежей позволяют хранить уникальные пары, тройки и т.д. Например, необходимо получить все возможные уникальные пары значений из двух списков (декартово произведение).

Пример
names = ['Alice', 'Bob']
roles = ['admin', 'user', 'guest']
unique_pairs = {(name, role) for name in names for role in roles}
print(unique_pairs)
# Результат: {('Alice', 'admin'), ('Alice', 'user'), ('Alice', 'guest'), ('Bob', 'admin'), ('Bob', 'user'), ('Bob', 'guest')}
# Вывод (порядок может отличаться):
# {('Alice', 'admin'), ('Alice', 'user'), ('Alice', 'guest'), ('Bob', 'admin'), ('Bob', 'user'), ('Bob', 'guest')}

Если списки содержат повторяющиеся элементы, множество автоматически уберёт дублирующиеся комбинации.

Как быстро проверить наличие хотя бы одного элемента из одного списка в другом (без пересечения)?

Использование any() и множества: any(item in set_b for item in a). Это останавливается на первом совпадении.

Пример
a = [1, 2, 3]
b = [3, 4, 5]
set_b = set(b)
print(any(x in set_b for x in a))  # True

Такой подход может быть быстрее чем not set_a.isdisjoint(set_b), если списки большие и пересекаются рано, но в целом метод isdisjoint() предпочтительнее.

Как удалить дубликаты из списка списков, используя frozenset?

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

Пример
data = [[1, 2], [2, 1], [1, 2], [3, 4]]
# Если порядок внутри подсписка не важен, используем frozenset для удаления дубликатов
unique_frozensets = {frozenset(sublist) for sublist in data}
print(unique_frozensets)  # {frozenset({1, 2}), frozenset({3, 4})}
# Результат: {frozenset({1, 2}), frozenset({3, 4})}

Если порядок важен, следует использовать кортежи: tuple(sublist).

Как найти общие элементы трёх и более списков?

Можно применить функцию reduce из модуля functools для последовательного пересечения множеств.

Пример
from functools import reduce

lists = [
    [1, 2, 3, 4],
    [3, 4, 5, 6],
    [3, 4, 7, 8]
]
sets = [set(lst) for lst in lists]
common = reduce(lambda a, b: a & b, sets)
print(common)  # {3, 4}
# Вывод: {3, 4}

Как изменить множество в процессе итерации по нему (избегая RuntimeError)?

Нельзя добавлять или удалять элементы из множества во время итерации с помощью for x in s (возникнет RuntimeError: Set changed size during iteration). Решение — работать с копией множества.

Пример
s = {1, 2, 3, 4}
# Удаление всех чётных элементов (неверно: for x in s: if x%2==0: s.remove(x))
# Верный способ:
for x in list(s):
    if x % 2 == 0:
        s.remove(x)  # или s.discard(x)
print(s)  # {1, 3}

Или использовать генератор нового множества: {x for x in s if x % 2 != 0}.

Как найти все числа от 1 до 100, которые делятся на 3 или на 5, но не на 15, с помощью множеств?

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

Пример
all_numbers = set(range(1, 101))
div3 = {x for x in all_numbers if x % 3 == 0}
div5 = {x for x in all_numbers if x % 5 == 0}
div15 = {x for x in all_numbers if x % 15 == 0}
result = (div3 | div5) - div15
print(sorted(result)[:10])  # [3, 5, 6, 9, 10, 12, 18, 20, 21, 24] (первые 10)
# Частичный вывод: [3, 5, 6, 9, 10, 12, 18, 20, 21, 24]

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

Операция in для множества имеет среднюю сложность O(1), для списка O(n). На больших данных разница колоссальна.

Пример
import time

big_list = list(range(100000))
big_set = set(big_list)
search = 99999

start = time.time()
result = search in big_list
print('List time:', time.time() - start)

start = time.time()
result = search in big_set
print('Set time:', time.time() - start)
# Примерный вывод:
# List time: 0.0026
# Set time: 0.000002

Это объясняет, почему для частых проверок наличия следует использовать множества.

Как выполнять операции с множествами, не изменяя исходные (получение копии)?

Операции &, -, ^, | всегда возвращают новое множество. Методы intersection(), difference() и другие без суффикса _update также не изменяют исходные множества.

Пример
a = {1, 2, 3}
b = {2, 3, 4}
c = a & b  # a и b не изменились
print(a)  # {1, 2, 3}
print(b)  # {2, 3, 4}
print(c)  # {2, 3}

Методы с суффиксом _update (например, intersection_update()) изменяют множество на месте.

Задачи на множества в Python - comments

En
множество python задачи (python)