Словари
Список хранит значения по номерам: a[0], a[1], … А что если удобнее искать не по номеру, а по названию: цена по имени товара, телефон по имени человека, количество по слову? Для этого есть словари.
Словарь: ключ → значение
prices = {"хлеб": 45, "молоко": 89, "сыр": 320}
print(prices["молоко"]) # 89
Словарь хранит пары ключ: значение. По ключу значение находится сразу, без перебора — так же быстро, как проверка во множестве.
Добавить или изменить значение:
prices["чай"] = 150 # новый ключ — пара добавится
prices["хлеб"] = 50 # существующий — значение заменится
print(len(prices)) # 4
Ключ в словаре всегда один: повторная запись по тому же ключу перезаписывает значение.
Нет такого ключа
Обращение к отсутствующему ключу — ошибка KeyError:
print(prices["кофе"]) # KeyError
Варианты:
if "кофе" in prices: # проверка ключа
print(prices["кофе"])
print(prices.get("кофе")) # None — ключа нет
print(prices.get("кофе", 0)) # 0 — своё значение по умолчанию
Удалить ключ: del prices["сыр"] или prices.pop("сыр").
Перебор словаря
ages = {"Аня": 12, "Боря": 14, "Вика": 13}
for name in ages: # перебираются ключи
print(name)
for name, age in ages.items(): # пары ключ-значение
print(name, age)
print(list(ages.values())) # [12, 14, 13]
print(sorted(ages)) # ключи по алфавиту
Словарь помнит порядок, в котором добавлялись ключи. Если нужен другой порядок — сортируй.
Подсчёт частот
Самое частое применение словаря — посчитать, сколько раз встречается каждое значение:
words = "кот пёс кот рыба пёс кот".split()
count = {}
for w in words:
count[w] = count.get(w, 0) + 1
print(count) # {'кот': 3, 'пёс': 2, 'рыба': 1}
count.get(w, 0) возвращает текущее число или 0, если слово встретилось впервые.
Ключ с наибольшим значением можно найти обычным перебором или через max(count, key=count.get) — но помни, что при равенстве max вернёт первый такой ключ в порядке словаря.
Counter
Для подсчёта есть готовый инструмент:
from collections import Counter
c = Counter("abracadabra")
print(c["a"]) # 5
print(c.most_common(2)) # [('a', 5), ('b', 2)]
Группировка
Значением словаря может быть что угодно, например список. Так группируют данные по признаку:
words = ["арбуз", "банан", "абрикос", "брусника", "вишня"]
by_letter = {}
for w in words:
first = w[0]
if first not in by_letter:
by_letter[first] = []
by_letter[first].append(w)
print(by_letter["б"]) # ['банан', 'брусника']
Ключом может быть любое неизменяемое значение: число, строка, кортеж. Например, координаты (x, y) — хороший ключ, а список — нет. Если нужно сгруппировать по «набору» значений, превращай его в строку или кортеж.
Словарь вместо длинного if
days = {1: "пн", 2: "вт", 3: "ср", 4: "чт", 5: "пт", 6: "сб", 7: "вс"}
n = int(input())
print(days.get(n, "нет такого дня"))
Итог
- словарь — пары
ключ: значение, доступd[ключ]работает мгновенно; - запись по существующему ключу заменяет значение;
in,get(ключ, по_умолчанию)защищают отKeyError;items(),keys(),values()— перебор;d[x] = d.get(x, 0) + 1— подсчёт частот;Counter— то же готовое;- ключи — только неизменяемые значения: числа, строки, кортежи.