Python · Синтаксис · Початковий рівень

Методи множин

10 завдань

Навчіться працювати з множинами: додавати та видаляти елементи, а також виконувати операції об'єднання, перетину та різниці.

Методи множин

#
Множина — це невпорядкована колекція **унікальних** елементів. Множини мутабельні, але елементи мають бути хешабельними (незмінні типи: рядки, числа, кортежі). Множини не підтримують індексування — `s[0]` неможливо. ## Створення множин ```python s = {1, 2, 3} empty = set() # НЕ {} — це створює порожній словник! from_list = set([1, 2, 2, 3, 3]) print(from_list) # {1, 2, 3} — дублікати видаляються автоматично ``` ## Додавання і видалення ```python s = {1, 2, 3} s.add(4) # додає 4 до множини s.add(2) # без ефекту — 2 вже є print(s) # {1, 2, 3, 4} s.remove(3) # видаляє 3 — кидає KeyError якщо немає s.discard(99) # видаляє 99 якщо є — БЕЗ помилки якщо немає print(s) # {1, 2, 4} popped = s.pop() # видаляє і повертає ДОВІЛЬНИЙ елемент print(popped) # якийсь елемент (порядок невизначений) s.clear() # видаляє всі елементи print(s) # set() ``` ## Операції над множинами ```python a = {1, 2, 3, 4} b = {3, 4, 5, 6} # Об'єднання: всі елементи з обох print(a | b) # {1, 2, 3, 4, 5, 6} print(a.union(b)) # те саме # Перетин: тільки елементи, що є В ОБОХ print(a & b) # {3, 4} print(a.intersection(b)) # те саме # Різниця: є в A, але НЕ в B print(a - b) # {1, 2} print(a.difference(b)) # те саме # Симетрична різниця: є в A або B, але НЕ в обох print(a ^ b) # {1, 2, 5, 6} print(a.symmetric_difference(b)) # те саме ``` ## Перевірка підмножин і надмножин ```python small = {1, 2} big = {1, 2, 3, 4} print(small.issubset(big)) # True — вся small є у big print(small <= big) # те саме через оператор print(big.issuperset(small)) # True — big містить всю small print(big >= small) # те саме print(small.isdisjoint({5, 6})) # True — спільних елементів немає ``` ## Оновлення на місці ```python a = {1, 2, 3} a.update({3, 4, 5}) # додає всі елементи (як |=) print(a) # {1, 2, 3, 4, 5} a.intersection_update({2, 3}) # залишає тільки спільні елементи print(a) # {2, 3} a.difference_update({3}) # видаляє елементи з аргументу print(a) # {2} ```

Практичні задачі з множинами

#
## Дедублікація Найпоширеніше використання множин: видалення дублікатів зі списку. ```python numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] unique = list(set(numbers)) print(sorted(unique)) # [1, 2, 3, 4, 5, 6, 9] ``` Зверніть увагу: перетворення у множину втрачає початковий порядок. Щоб зберегти порядок при видаленні дублікатів: ```python def deduplicate(lst): seen = set() result = [] for item in lst: if item not in seen: seen.add(item) result.append(item) return result print(deduplicate([3, 1, 4, 1, 5, 9, 2, 6, 5])) # [3, 1, 4, 5, 9, 2, 6] ``` ## Пошук спільних і унікальних елементів ```python team_a = {"Alice", "Bob", "Carol", "David"} team_b = {"Bob", "David", "Eve", "Frank"} # Хто є в обох командах? both = team_a & team_b print(both) # {"Bob", "David"} # Хто тільки в команді A? only_a = team_a - team_b print(only_a) # {"Alice", "Carol"} # Всі учасники (без дублікатів) everyone = team_a | team_b print(everyone) # {"Alice", "Bob", "Carol", "David", "Eve", "Frank"} # Хто рівно в одній команді? exclusive = team_a ^ team_b print(exclusive) # {"Alice", "Carol", "Eve", "Frank"} ``` ## Перевірка членства ```python # Пошук у множині — O(1), набагато швидший за список для великих колекцій allowed_extensions = {".jpg", ".jpeg", ".png", ".gif", ".webp"} def is_image(filename): _, ext = filename.rsplit(".", 1) if "." in filename else (filename, "") return f".{ext.lower()}" in allowed_extensions print(is_image("photo.jpg")) # True print(is_image("doc.pdf")) # False print(is_image("readme.txt")) # False ``` ## Set comprehension ```python words = ["hello", "world", "hello", "python", "world"] unique_words = {w.lower() for w in words} print(unique_words) # {"hello", "world", "python"} # Унікальні перші літери first_letters = {word[0] for word in ["apple", "banana", "avocado", "cherry"]} print(sorted(first_letters)) # ["a", "b", "c"] ```

Довідник: методи множин

#
## Методи, що модифікують | Метод | Що робить | |---|---| | `s.add(x)` | Додати `x` до множини | | `s.remove(x)` | Видалити `x` (кидає `KeyError` якщо немає) | | `s.discard(x)` | Видалити `x` якщо є, без помилки якщо немає | | `s.pop()` | Видалити і повернути довільний елемент | | `s.clear()` | Видалити всі елементи | | `s.update(other)` | Додати всі елементи з `other` до `s` | | `s.intersection_update(other)` | Залишити тільки спільні елементи | | `s.difference_update(other)` | Видалити елементи з `other` | ## Операції над множинами — методи та оператори | Операція | Метод | Оператор | Результат | |---|---|---|---| | Об'єднання | `a.union(b)` | `a | b` | Всі елементи A і B | | Перетин | `a.intersection(b)` | `a & b` | Тільки є в A і B | | Різниця | `a.difference(b)` | `a - b` | Є в A, немає в B | | Симетрична різниця | `a.symmetric_difference(b)` | `a ^ b` | В A або B, але не в обох | | Підмножина | `a.issubset(b)` | `a <= b` | Вся A є у B | | Надмножина | `a.issuperset(b)` | `a >= b` | A містить всю B | | Відсутність перетину | `a.isdisjoint(b)` | — | A і B не мають спільних елементів | ## Оператори vs методи Оператори (`|`, `&`, `-`, `^`) вимагають, щоб **обидва операнди були множинами**. Методи (`.union()`, `.intersection()` тощо) приймають **будь-який ітерабельний** об'єкт: ```python s = {1, 2, 3} s.union([3, 4, 5]) # OK — список приймається s | [3, 4, 5] # TypeError — оператор потребує множину ``` ## Set comprehension ```python {вираз for змінна in ітерабельний} {вираз for змінна in ітерабельний if умова} ``` ## Поширені патерни ```python # Дедублікація зі збереженням порядку seen = set() result = [x for x in lst if not (x in seen or seen.add(x))] # Швидка перевірка членства VALID = {"admin", "editor", "viewer"} if role not in VALID: raise ValueError(f"Unknown role: {role}") # Спільні елементи кількох множин common = set.intersection(*list_of_sets) ```
01

Безпечне видалення

#

Напишіть функцію `safe_remove(s, value)`, яка видаляє `value` з множини `s` якщо він є, і повертає `True` якщо видалено або `False` якщо не знайдено. Функція ніколи не повинна кидати помилку. Приклад: `s = {1, 2, 3}; safe_remove(s, 2)` → `True`, `s == {1, 3}`; `safe_remove(s, 99)` → `False`.

def safe_remove(s, value):
    pass


s = {1, 2, 3}
print(safe_remove(s, 2))    # True  (s тепер {1, 3})
print(safe_remove(s, 99))   # False
Рішення
def safe_remove(s, value):
    if value in s:
        s.discard(value)
        return True
    return False


s = {1, 2, 3}
print(safe_remove(s, 2))    # True
print(safe_remove(s, 99))   # False
02

Видалити дублікати зі збереженням порядку

#

Напишіть функцію `unique_ordered(lst)`, яка видаляє дублікати зі списку зі збереженням порядку першої появи. Приклад: `unique_ordered([3, 1, 4, 1, 5, 9, 2, 6, 5, 3])` → `[3, 1, 4, 5, 9, 2, 6]`. Використовуйте множину для відстеження побачених елементів.

def unique_ordered(lst):
    pass


print(unique_ordered([3, 1, 4, 1, 5, 9, 2, 6, 5, 3]))
# [3, 1, 4, 5, 9, 2, 6]
Рішення
def unique_ordered(lst):
    seen = set()
    result = []
    for item in lst:
        if item not in seen:
            seen.add(item)
            result.append(item)
    return result


print(unique_ordered([3, 1, 4, 1, 5, 9, 2, 6, 5, 3]))
# [3, 1, 4, 5, 9, 2, 6]
03

Спільні елементи

#

Напишіть функцію `common(a, b)`, яка повертає множину елементів, що є у обох списках `a` і `b`. Приклад: `common([1, 2, 3, 4], [3, 4, 5, 6])` → `{3, 4}`. Перетворіть на множини і використайте операцію перетину.

def common(a, b):
    pass


print(common([1, 2, 3, 4], [3, 4, 5, 6]))
# {3, 4}
Рішення
def common(a, b):
    return set(a) & set(b)


print(common([1, 2, 3, 4], [3, 4, 5, 6]))
# {3, 4}
04

Тільки в одному

#

Напишіть функцію `exclusive(a, b)`, яка повертає множину елементів, що є рівно в одному з двох списків (але не в обох). Приклад: `exclusive([1, 2, 3], [2, 3, 4])` → `{1, 4}`. Використайте операцію симетричної різниці.

def exclusive(a, b):
    pass


print(exclusive([1, 2, 3], [2, 3, 4]))
# {1, 4}
Рішення
def exclusive(a, b):
    return set(a) ^ set(b)


print(exclusive([1, 2, 3], [2, 3, 4]))
# {1, 4}
05

Перевірка підмножини

#

Напишіть функцію `is_subset(small, big)`, яка повертає `True`, якщо кожен елемент `small` також є у `big`. Обидва аргументи можуть бути списками або множинами. Приклад: `is_subset([1, 2], [1, 2, 3, 4])` → `True`, `is_subset([1, 5], [1, 2, 3])` → `False`.

def is_subset(small, big):
    pass


print(is_subset([1, 2], [1, 2, 3, 4]))    # True
print(is_subset([1, 5], [1, 2, 3]))        # False
Рішення
def is_subset(small, big):
    return set(small) <= set(big)


print(is_subset([1, 2], [1, 2, 3, 4]))    # True
print(is_subset([1, 5], [1, 2, 3]))        # False
06

Кількість унікальних слів

#

Напишіть функцію `unique_word_count(text)`, яка повертає кількість унікальних слів у рядку (без урахування регістру). Приклад: `unique_word_count("The cat sat on the mat the cat")` → `5` (the, cat, sat, on, mat).

def unique_word_count(text):
    pass


print(unique_word_count("The cat sat on the mat the cat"))
# 5  (the, cat, sat, on, mat)
Рішення
def unique_word_count(text):
    return len(set(text.lower().split()))


print(unique_word_count("The cat sat on the mat the cat"))
# 5  (the, cat, sat, on, mat)
07

Допустимі символи

#

Напишіть функцію `has_only_valid(s, allowed)`, яка повертає `True`, якщо кожен символ рядка `s` міститься у рядку `allowed`. Приклад: `has_only_valid("hello", "aehllo")` → `True`, `has_only_valid("hello!", "aehllo")` → `False`. Використайте операції над множинами.

def has_only_valid(s, allowed):
    pass


print(has_only_valid("hello", "aehllo"))    # True
print(has_only_valid("hello!", "aehllo"))   # False
Рішення
def has_only_valid(s, allowed):
    return set(s) <= set(allowed)


print(has_only_valid("hello", "aehllo"))    # True
print(has_only_valid("hello!", "aehllo"))   # False
08

Set Comprehension

#

Напишіть функцію `vowel_set(text)`, яка повертає множину всіх унікальних голосних (a, e, i, o, u), що зустрічаються у `text` (без урахування регістру). Використайте set comprehension. Приклад: `vowel_set("Hello World")` → `{"e", "o"}`.

def vowel_set(text):
    pass


print(vowel_set("Hello World"))   # {"e", "o"}
print(vowel_set("Python"))        # {"o"}
Рішення
def vowel_set(text):
    vowels = "aeiou"
    return {ch for ch in text.lower() if ch in vowels}


print(vowel_set("Hello World"))   # {"e", "o"}
print(vowel_set("Python"))        # {"o"}
09

Діаграма Вена

#

Студенти можуть записатись у Клуб A, Клуб B або обидва. З двох множин `club_a` і `club_b` з іменами студентів напишіть функцію `venn(club_a, club_b)`, яка повертає словник з трьома ключами: `"only_a"` (тільки в A), `"only_b"` (тільки в B), `"both"` (в обох). Приклад: `venn({"Alice", "Bob", "Carol"}, {"Bob", "Carol", "David"})` → `{"only_a": {"Alice"}, "only_b": {"David"}, "both": {"Bob", "Carol"}}`.

def venn(club_a, club_b):
    pass


result = venn({"Alice", "Bob", "Carol"}, {"Bob", "Carol", "David"})
print(result["only_a"])   # {"Alice"}
print(result["only_b"])   # {"David"}
print(result["both"])     # {"Bob", "Carol"}
Рішення
def venn(club_a, club_b):
    return {
        "only_a": club_a - club_b,
        "only_b": club_b - club_a,
        "both":   club_a & club_b,
    }


result = venn({"Alice", "Bob", "Carol"}, {"Bob", "Carol", "David"})
print(result["only_a"])   # {"Alice"}
print(result["only_b"])   # {"David"}
print(result["both"])     # {"Bob", "Carol"}
10

Спільне для всіх множин

#

Напишіть функцію `common_all(*lists)`, яка повертає множину елементів, що є у ВСІХ переданих списках. Приклад: `common_all([1, 2, 3], [2, 3, 4], [2, 3, 5])` → `{2, 3}`. Обробіть випадок коли списків не передано (повернути порожню множину).

def common_all(*lists):
    pass


print(common_all([1, 2, 3], [2, 3, 4], [2, 3, 5]))   # {2, 3}
print(common_all([1, 2], [3, 4]))                     # set()
print(common_all())                                   # set()
Рішення
def common_all(*lists):
    if not lists:
        return set()
    result = set(lists[0])
    for lst in lists[1:]:
        result &= set(lst)
    return result


print(common_all([1, 2, 3], [2, 3, 4], [2, 3, 5]))   # {2, 3}
print(common_all([1, 2], [3, 4]))                     # set()
print(common_all())                                   # set()