Что такое словарь
Словарь (dict) — это коллекция пар
«ключ-значение». К каждому значению обращаются по ключу, а не по индексу.
Создаётся фигурными скобками:
user = {
"name": "Анна",
"age": 28,
"city": "Москва",
}
print(user["name"]) # Анна
print(user["age"]) # 28
Ключи должны быть уникальны и неизменяемы (строки, числа, кортежи). Значения — любые.
Доступ и добавление
user = {"name": "Анна", "age": 28}
# Чтение
print(user["name"]) # Анна
# Обращение к несуществующему ключу — KeyError
# print(user["email"]) # ошибка!
# Безопасный доступ через get()
print(user.get("email")) # None
print(user.get("email", "нет")) # "нет" — значение по умолчанию
# Добавление и изменение
user["email"] = "anna@example.com" # новый ключ
user["age"] = 29 # изменение существующего
Методы словаря
user = {"name": "Анна", "age": 28, "city": "Москва"}
print(user.keys()) # dict_keys(['name', 'age', 'city'])
print(user.values()) # dict_values(['Анна', 28, 'Москва'])
print(user.items()) # пары (ключ, значение)
# Перебор пар — самый частый сценарий
for key, value in user.items():
print(f"{key}: {value}")
Удаление
user = {"name": "Анна", "age": 28, "city": "Москва"}
del user["city"] # удалить по ключу
age = user.pop("age") # удалить и вернуть значение
user.clear() # очистить словарь
update() — слияние
defaults = {"theme": "light", "lang": "ru"}
user_prefs = {"theme": "dark"}
defaults.update(user_prefs)
print(defaults) # {'theme': 'dark', 'lang': 'ru'}
Проверка наличия ключа
Оператор in проверяет, есть ли ключ в словаре:
user = {"name": "Анна"}
if "email" in user:
print(user["email"])
else:
print("Email не указан")
Счётчик через get()
Классическая задача — посчитать, сколько раз встретился каждый элемент.
Решается словарём и безопасным чтением через get() с
значением по умолчанию 0:
words = ["яблоко", "банан", "яблоко", "груша", "банан", "яблоко"]
counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
print(counts) # {'яблоко': 3, 'банан': 2, 'груша': 1}
Читается так: «взять текущее значение (или 0, если ключа ещё нет), прибавить единицу и записать обратно».
setdefault() — добавить, если нет
setdefault(key, default) возвращает значение по ключу, а если
ключа нет — сначала вставляет default и возвращает его.
Для чисел разницы с get() почти нет, а вот для изменяемых
значений (список, множество) метод незаменим — он даёт объект, который тут же
можно дополнить:
people = [("Москва", "Анна"), ("Питер", "Борис"), ("Москва", "Вера")]
by_city = {}
for city, name in people:
by_city.setdefault(city, []).append(name)
print(by_city) # {'Москва': ['Анна', 'Вера'], 'Питер': ['Борис']}
Без setdefault пришлось бы каждый раз писать
if city not in by_city: by_city[city] = [].
Словарные выражения
Аналог list comprehension для словарей:
# Квадраты чисел как ключ-значение
squares = {n: n ** 2 for n in range(1, 6)}
# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# Инвертировать словарь (поменять ключи и значения)
original = {"a": 1, "b": 2}
inverted = {v: k for k, v in original.items()}
# {1: 'a', 2: 'b'}
zip() — склеить два списка
Функция zip() идёт по нескольким последовательностям
одновременно и выдаёт кортежи из соответствующих элементов:
keys = ["name", "age", "city"]
values = ["Анна", 28, "Москва"]
for k, v in zip(keys, values):
print(k, "=", v)
# name = Анна
# age = 28
# city = Москва
Отсюда самый короткий способ собрать словарь из двух списков —
передать zip() прямо в dict():
user = dict(zip(keys, values))
print(user) # {'name': 'Анна', 'age': 28, 'city': 'Москва'}
Если списки разной длины, zip() останавливается на самом
коротком — «лишние» элементы просто игнорируются.
Множества (set)
Множество — это коллекция уникальных элементов.
Создаётся через set() или фигурные скобки (но не пустые —
{} создаёт словарь):
numbers = {1, 2, 3, 2, 1} # {1, 2, 3} — дубликаты схлопнутся
print(numbers)
# Получить уникальные элементы списка
tags = ["python", "web", "python", "django", "web"]
unique = set(tags)
print(unique) # {'python', 'web', 'django'}
Операции над множествами
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a & b) # {3, 4} — пересечение
print(a | b) # {1, 2, 3, 4, 5, 6} — объединение
print(a - b) # {1, 2} — разность
print(a ^ b) # {1, 2, 5, 6} — симметрическая разность
Проверка принадлежности в множестве очень быстрая (O(1)), поэтому его
используют вместо списка для in:
allowed = {"admin", "editor"} # множество
# allowed = ["admin", "editor"] # список — медленнее для in
if role in allowed:
print("Доступ открыт")
Какую структуру выбрать
| Задача | Структура |
|---|---|
| Упорядоченный набор элементов | list |
| Неизменяемая последовательность | tuple |
| Связь ключа со значением | dict |
| Уникальные элементы, быстрая проверка принадлежности | set |
| Конфигурация, профиль пользователя | dict |
Кейс 1: конфигурация приложения
Словарь — естественный способ хранить настройки. Ключи — строки, значения — любые типы:
config = {
"debug": True,
"port": 8000,
"database": {
"host": "localhost",
"name": "myapp",
},
"allowed_hosts": ["localhost", "127.0.0.1"],
}
# Вложенный доступ
print(config["database"]["host"]) # localhost
print(config["port"]) # 8000
# Безопасное чтение с дефолтом
debug = config.get("debug", False)
Кейс 2: счётчик уникальных посетителей
Сочетание словаря и множества — частый паттерн в аналитике:
logs = [
("2024-01-01", "user1"),
("2024-01-01", "user2"),
("2024-01-01", "user1"), # повтор user1
("2024-01-02", "user3"),
("2024-01-02", "user1"),
]
visitors_per_day = {}
for date, user in logs:
visitors_per_day.setdefault(date, set()).add(user)
for date, users in visitors_per_day.items():
print(f"{date}: уникальных — {len(users)}")
# 2024-01-01: уникальных — 2
# 2024-01-02: уникальных — 2
Типичные ошибки
1. KeyError на несуществующем ключе
user = {"name": "Анна"}
# print(user["email"]) # KeyError
print(user.get("email")) # None — безопасно
2. Список как ключ словаря
# d = {[1, 2]: "value"} # TypeError: unhashable type: 'list'
d = {(1, 2): "value"} # кортеж — можно
3. Путаница {} и set()
empty_dict = {} # это словарь, не множество!
empty_set = set() # а вот так — множество
Практика
- Создайте словарь с данными о книге (title, author, year). Выведите значение по ключу
author. - Посчитайте частоту каждого символа в строке
"hello world"через словарь. - Даны два списка: ключи и значения. Соберите из них словарь через
zip(). - Найдите пересечение и объединение двух множеств
{1,2,3}и{3,4,5}. - Инвертируйте словарь
{"a": 1, "b": 2, "c": 3}через dict comprehension.
Итог
Словарь — главная структура для пар «ключ-значение», а множество — для
уникальных элементов и быстрых проверок принадлежности. Мы разобрали методы,
comprehensions, безопасный доступ через get(), счётчики,
setdefault(), склейку списков через zip() и операторы
над множествами. В следующей главе научимся группировать код в функции.