Лекция № 6. Составные типы данных “Словарь” и “Множество”

Хорошевич Павел Александрович

Тип данных “Словарь”

Инициализация

Словарь – это набор ключей и соответствующих им значений.

В Python словарю соответствует тип dict.

d = {}      # пустой словарь
d = dict()  # второй способ создать пустой словарь

Добавление и получение значений из словаря

Квадратные скобки [] позволяют добавить и получить значение из словаря.

bel2rus = {}
bel2rus["гарбуз"] = "тыква"
bel2rus["гузiк"] = "пуговица"
bel2rus["цмок"] = "дракон"

print(bel2rus)
print(bel2rus["гузiк"]) # получаем значение по ключу "гузiк"

Словарь можно заполнить при его создании:

bel2rus = {"цмок": "дракон", "гузiк": "пуговица", "гарбуз": "тыква"}
print(bel2rus)

Данные в словаре не упорядочены.

bel2rus = {"цмок": "дракон", "гузiк": "пуговица", "гарбуз": "тыква"}
flowchart LR
    subdict["📦 Словарь: bel2rus"]

    subdict --> k1["🔑 'гарбуз'"]
    subdict --> k2["🔑 'гузік'"]
    subdict --> k3["🔑 'цмок'"]

    k1 --> v1["💬 'тыква'"]
    k2 --> v2["💬 'пуговица'"]
    k3 --> v3["💬 'дракон'"]

    style subdict fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
    style k1 fill:#fff9c4,stroke:#fbc02d
    style k2 fill:#fff9c4,stroke:#fbc02d
    style k3 fill:#fff9c4,stroke:#fbc02d
    style v1 fill:#e8f5e9,stroke:#2e7d32
    style v2 fill:#e8f5e9,stroke:#2e7d32
    style v3 fill:#e8f5e9,stroke:#2e7d32
Рисунок 1: Словарь bel2rus

Тип ключей в словаре

Ключами в словаре могут быть значению любого неизменяемого типа: int, float, str.

Целочисленный ключ, строковое значение:

num_names = {1:"Один", 2: "Два", 3:"Три"} 

Вещественный ключ, строковое значение:

dec_names = {1.5:"Одна целая, пять десятых", 2.5: "Два с половиной"}

Строковый ключ, целочисленное значение:

roman_nums = {'I':1, 'II':2, 'III':3, 'IV':4, 'V':5}

Строковый ключ, значение - список:

shop = {'фрукты': ['ананас', 'банан'], 'овощи': ['огурец', 'капуста']}
flowchart LR
    shop["📦 shop<br><i>(dict)</i>"]
    
    k1["🔑 'фрукты'"]
    k2["🔑 'овощи'"]
    
    l1["📋 list"]
    l2["📋 list"]
    
    v1["'ананас'"]
    v2["'банан'"]
    v3["'огурец'"]
    v4["'капуста'"]
    
    shop --- k1
    shop --- k2
    
    k1 --> l1
    k2 --> l2
    
    l1 -- "0" --> v1
    l1 -- "1" --> v2
    l2 -- "0" --> v3
    l2 -- "1" --> v4
    
    classDef dict fill:#dbeafe,stroke:#2563eb,stroke-width:2px,color:#1e3a8a
    classDef key fill:#fef9c3,stroke:#ca8a04,color:#713f12
    classDef lst fill:#dcfce7,stroke:#16a34a,color:#14532d
    classDef str fill:#f3e8ff,stroke:#9333ea,color:#581c87
    
    class shop dict
    class k1,k2 key
    class l1,l2 lst
    class v1,v2,v3,v4 str
Рисунок 2: Словарь shop

Каково значение выражения shop["фрукты"][1]?

Метод get()

Если попытаться получить значение по ключу, которого нет в словаре, возникнет ошибка:

student = {"имя": "Павел", "возраст": 20, "отметка": 9}
print(student["фамилия"])  # ошибка: ключ не найден!

Метод get() позволяет безопасно получать значения:

student = {"имя": "Павел", "возраст": 20, "отметка": 9}

print(student.get("фамилия"))           # вернёт None
print(student.get("возраст"))           # вернёт 20
print(student.get("курс", 1))           # вернёт 1, если ключа нет

Обновление словаря: метод update()

Метод update() добавляет новые пары ключ-значение или обновляет существующие.

student = {"имя": "Павел", "возраст": 20}

# добавляем новый ключ
student.update({"отметка": 9})
print(student)

# обновляем существующее значение
student.update({"возраст": 21})
print(student)

Можно объединять два словаря:

dict1 = {"a": 1, "b": 2}
dict2 = {"b": 20, "c": 3}

dict1.update(dict2)
print(dict1)  # {'a': 1, 'b': 20, 'c': 3}

Если ключи совпадают, значение из обновляющего словаря перезаписывает старое.

Получение списка ключей и значений

Методы keys() и values() возвращают список ключей и значений словаря соответственно.

roman_nums = {'I': 1, 'II': 2, 'III': 3, 'IV': 4, 'V': 5}

print(list(roman_nums.keys()))    # ['I', 'II', 'III', 'IV', 'V']
print(list(roman_nums.values()))  # [1, 2, 3, 4, 5]

Перебор ключей словаря:

for key in roman_nums.keys():
    print(key, roman_nums[key])

Оператор in для словарей

Оператор in проверяет наличие ключа в словаре:

goods = {"тетрадь": 12, "ручка": 6, "блокнот": 23}

print("ручка" in goods)      # True
print("карандаш" in goods)   # False
print(12 in goods)           # False [!]

Пример № 1

Посчитать сколько раз наименование товара встречается на складе. Название товара вводится с клавиатуры.

inventory = {}

for i in range(5):
    item = input("Товар > ")
    if item in inventory:
        inventory[item] += 1
    else:
        inventory[item] = 1

print(inventory)

Пример № 2

Напишите программу-переводчик с английского на русский язык.

eng2rus = {
    "cat": "кот",
    "dog": "собака",
    "bird": "птица"
}

all_eng_words = eng2rus.keys() # список ключей
joined_keys = ", ".join(all_eng_words)
print("Доступные слова:", joined_keys)

word = input("Введите слово для перевода: ")
translation = eng2rus.get(word, "Слово не найдено")
print("Перевод:", translation)

Пример № 3

Посчитайте сколько раз встречается каждое слово в строке.

text = "кот кот собака птица кот собака"
words = text.split() # список слов

freq = {}
for w in words:
    freq[w] = freq.get(w, 0) + 1

for word in freq.keys():
    print(f"{word}: {freq[word]}")
Таблица 1: Основные методы работы со словарями
Метод Назначение
d.get(key) Безопасное получение значения
d.get(key, default) Получение с значением по умолчанию
d.update(other) Обновление словаря другим словарём
d.keys() Получение коллекции ключей
d.values() Получение коллекции значений
d.items() Получение коллекции пар (ключ, значение)

Вопрос? Вопрос. Вопрос!

shop = {"фрукты": ["яблоко", "банан"], "овощи": ["огурец", "капуста"]}
  • shop["фрукты"][0]

  • "банан" in shop

  • shop.get("мясо", "нет в наличии")

  • list(shop.keys())

  • len(shop.values())

Тип данных “Множество”

Инициализация множества

Множество - это неупорядоченная коллекция уникальных элементов. В Python множеству соответствует тип set.

# пустое множество
s = set()

# множество с элементами
prostye = {2, 3, 5, 7, 11}
glasnye = set("аеёиоуыэюя")
colors = {"красный", "зелёный", "синий"}

Пустые фигурные скобки {} создают пустой словарь, а не множество!

type({})    # <class 'dict'>
type(set()) # <class 'set'>
flowchart LR
    set_node["📦 <b>colors</b><br><i>(тип: set)</i>"]
    
    item1["🔴 'красный'"]
    item2["🟢 'зелёный'"]
    item3["🔵 'синий'"]
    
    set_node --- item1
    set_node --- item2
    set_node --- item3
    
    classDef setStyle fill:#f8fafc,stroke:#475569,stroke-width:2px,stroke-dasharray:6 4,color:#1e293b
    classDef itemStyle fill:#ffffff,stroke:#94a3b8,stroke-width:1px,color:#334155
    
    class set_node setStyle
    class item1,item2,item3 itemStyle
Рисунок 3: Множество colors

Что выведет на экран print(colors[0])?

Добавление и удаление элементов

Таблица 2: Основные методы множества
Метод Назначение
s.add(x) Добавить элемент x в множество
s.discard(x) Удалить элемент x
s.clear() Очистить множество
nums = set()
nums.add(5)
nums.add(3)
nums.add(5)  # повтор не добавится

print(nums)  # {3, 5}
nums.discard(10)  # ошибки не будет

Перебор элементов множества

Элементы множества можно перебирать циклом for:

colors = {"красный", "зелёный", "синий"}

for color in colors:
    print("Цвет:", color)

Порядок элементов в множестве не гарантируется и может отличаться от порядка добавления.

Проверка наличия элемента

Оператор in проверяет принадлежность элемента множеству:

glasnye = {"а", "е", "ё", "и", "о", "у", "ы", "э", "ю", "я"}

print("а" in glasnye)      # True
print("б" in glasnye)      # False
print("к" not in glasnye)  # True

Операции над множествами

Объединение

A | B

A.union(B)

Пересечение

A & B

A.intersection(B)

Разность

A - B

A.difference(B)

Симметричная разность

A ^ B

A.symmetric_difference(B)

Примеры:

A = {1, 2, 3, 4}
B = {3, 4, 5, 6}

print(A | B)  # {1, 2, 3, 4, 5, 6}
print(A & B)  # {3, 4}
print(A - B)  # {1, 2}
print(A ^ B)  # {1, 2, 5, 6}

Пример № 4

Даны два множества:

  • phys - фамилии студентов, участвующих в олимпиаде по физике;
  • math - фамилии студентов, участвующих в олимпиаде по математике.

Программа должна выполнить следующие операции над множествами:

  1. Найти пересечение (&): вывести фамилии студентов, участвующих в обеих олимпиадах.

  2. Найти объединение (|): вывести фамилии всех студентов, заявленных хотя бы на одну олимпиаду.

  1. Найти разность physics - math: вывести фамилии тех, кто участвует только в физической олимпиаде.

  2. Найти разность math - physics: вывести фамилии тех, кто участвует только в математической олимпиаде.

  3. Найти симметричную разность (^): вывести фамилии студентов, участвующих ровно в одной из олимпиад.

phys = {"Иванов", "Петрова", "Сидоров", "Козлов"}
math = {"Петрова", "Кузнецов", "Смирнова", "Сидоров"}

# Форматированный вывод множеств

# 1. Пересечение

# 2. Объединение

# 3. Первая разность

# 4. Вторая разность

# 5. Симметричная разность

Вопрос? Вопрос. Вопрос!

A = {1, 2, 3}
B = {2, 3, 4}
  • len(A)

  • A | B

  • A & B

  • 5 in A

  • A - B

Строки, списки, словари, множества

Таблица 3: Сравнение составных типов данных
str list dict set
Упорядоченность ✅ Да ✅ Да ❌ Нет ❌ Нет
Уникальность элементов ❌ Нет ❌ Нет 🟨 Ключи ✅ Да
Изменяемость ❌ Нет ✅ Да ✅ Да ✅ Да
Индексация ✅ По номеру ✅ По номеру ✅ По ключу ❌ Нет