Словарь в Python (тип dict) хранит данные парами «ключ: значение». Создают его фигурными скобками: user = {"name": "Анна", "age": 28}. Значение достают по ключу: user["name"] или user.get("name"), новый элемент добавляют присваиванием user["city"] = "Казань", а удаляют через del или pop().
От списка словарь отличается способом поиска: в списке Python элемент ищут по номеру, а в словаре по имени. Ниже пять способов создать dict, основные методы, перебор и пять частых ошибок с разбором. Примеры рассчитаны на Python 3.9 и новее, вывод показан для 3.14.
Что такое словарь в Python

Словарь похож на телефонную книжку. Вы не помните, на какой строке записан Борис, зато знаете имя и сразу получаете номер. В Python так же: ключ ведёт прямо к значению, перебирать всё подряд не нужно.
user = {"name": "Анна", "age": 28, "city": "Казань"}
empty = {}
print(user)
print(type(empty), len(user))
Результат:
{'name': 'Анна', 'age': 28, 'city': 'Казань'}
<class 'dict'> 3
Значением может быть что угодно: число, строка, список, другой словарь. С ключами строже, о них чуть ниже.
Чем словарь отличается от списка и множества
| Тип | Как выглядит | Как достать элемент | Когда брать |
|---|---|---|---|
Список list |
["Анна", 28] |
по номеру: a[0] |
важен порядок, бывают повторы |
Словарь dict |
{"name": "Анна"} |
по ключу: d["name"] |
у каждого значения есть имя |
Множество set |
{"Анна", "Борис"} |
никак, только проверка in |
нужны уникальные значения |
Пустые фигурные скобки {} дают словарь. Пустое множество пишут как set(), подробнее об этом в разборе множеств в Python.
Что годится в ключи
Ключом может быть только хешируемый объект: строка, число, кортеж из неизменяемых элементов. Список, другой словарь и любой изменяемый тип ключом стать не могут, об этом сказано в документации Python.
coords = {(55.75, 37.62): "Москва"}
print(coords[(55.75, 37.62)])
bad = {[1, 2]: "список"}
Результат:
Москва
TypeError: cannot use 'list' as a dict key (unhashable type: 'list')
В старых версиях, например в 3.9, текст той же ошибки короче: TypeError: unhashable type: 'list'. Если ключ из нескольких частей всё-таки нужен, превратите список в кортеж, как с координатами в примере.
Как создать словарь: 5 способов
Фигурные скобки
Самый частый вариант, его вы уже видели выше. Пары пишут через запятую, ключ от значения отделяет двоеточие.
Функция dict()
Удобна, если ключи записываются простыми словами: кавычки вокруг них не нужны. Ещё dict() принимает список пар.
user = dict(name="Анна", age=28)
pairs = dict([("RU", "Россия"), ("KZ", "Казахстан")])
print(user)
print(pairs)
Результат:
{'name': 'Анна', 'age': 28}
{'RU': 'Россия', 'KZ': 'Казахстан'}
Из двух списков через zip()
Ключи лежат в одном списке, значения в другом. zip() сшивает их попарно, а dict() собирает результат в словарь.
keys = ["Пн", "Вт", "Ср"]
hours = [8, 6, 7]
week = dict(zip(keys, hours))
print(week)
Результат:
{'Пн': 8, 'Вт': 6, 'Ср': 7}
Метод fromkeys()
Создаёт словарь с заданными ключами и одним значением для всех. Подходит для счётчиков и флажков.
scores = dict.fromkeys(["Анна", "Борис", "Вера"], 0)
print(scores)
Результат:
{'Анна': 0, 'Борис': 0, 'Вера': 0}
Значение здесь одно на всех. С числом это безопасно, со списком уже нет, разбор в разделе про ошибки.
Генератор словаря
Генератор словаря (dict comprehension) строит dict в одну строку по правилу. Запись та же, что у генератора списка, только в фигурных скобках и с двоеточием.
squares = {n: n ** 2 for n in range(1, 6)}
print(squares)
Результат:
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
Как получить значение по ключу
Есть два способа, и ведут они себя по-разному, когда ключа нет. Квадратные скобки останавливают программу ошибкой KeyError:
user = {"name": "Анна", "age": 28}
print(user["name"])
print(user["phone"])
Результат:
Анна
KeyError: 'phone'
Метод get() на отсутствующем ключе вернёт None или значение, которое вы передали вторым аргументом. По документации он никогда не вызывает KeyError.
user = {"name": "Анна", "age": 28}
print(user.get("phone"))
print(user.get("phone", "не указан"))
Результат:
None
не указан
Что выбрать: скобки там, где ключ обязан быть и его отсутствие означает баг. get() там, где ключа может не быть по сценарию: необязательное поле анкеты, настройка со значением по умолчанию. Все тонкости метода собраны в отдельной инструкции про get() в Python.
Как проверить, есть ли ключ в словаре
Оператор in у словаря проверяет только ключи. Чтобы поискать среди значений, нужен values(). Как in работает со строками и списками, показано в разборе операторов Python.
user = {"name": "Анна", "age": 28}
print("age" in user)
print("Анна" in user)
print("Анна" in user.values())
Результат:
True
False
True
Как добавить, изменить и удалить элемент
Добавить и изменить
Одна и та же запись d[ключ] = значение добавляет новый ключ или перезаписывает старый. Python не предупредит, что значение уже было.
user = {"name": "Анна"}
user["city"] = "Казань"
user["name"] = "Анна Петрова"
print(user)
Результат:
{'name': 'Анна Петрова', 'city': 'Казань'}
Чтобы обновить сразу несколько ключей, вызовите update(). Существующие ключи перезапишутся, новые добавятся.
user = {"name": "Анна", "city": "Казань"}
user.update({"city": "Москва", "age": 28})
print(user)
Результат:
{'name': 'Анна', 'city': 'Москва', 'age': 28}
Объединить два словаря
С Python 3.9 словари склеивают оператором |. Он возвращает новый словарь и не трогает исходные; при совпадении ключей побеждает правый. Оператор появился по PEP 584.
defaults = {"theme": "light", "lang": "ru"}
custom = {"theme": "dark"}
settings = defaults | custom
print(settings)
print(defaults)
Результат:
{'theme': 'dark', 'lang': 'ru'}
{'theme': 'light', 'lang': 'ru'}
Запись defaults |= custom делает то же самое, но меняет defaults на месте, как update().
Удалить элемент
del d[ключ]удаляет пару и ничего не возвращает;d.pop(ключ)удаляет пару и возвращает значение, а со вторым аргументом не падает на отсутствующем ключе;d.popitem()снимает последнюю добавленную пару;d.clear()очищает словарь целиком.
cart = {"хлеб": 60, "молоко": 95, "сыр": 450, "чай": 210}
del cart["хлеб"]
price = cart.pop("сыр")
print(price)
print(cart.pop("кофе", "нет в корзине"))
last = cart.popitem()
print(last)
print(cart)
cart.clear()
print(cart)
Результат:
450
нет в корзине
('чай', 210)
{'молоко': 95}
{}
Шпаргалка по методам словаря
| Метод | Что делает | Если ключа нет |
|---|---|---|
get(k, default) |
возвращает значение | вернёт default или None |
setdefault(k, v) |
возвращает значение, а отсутствующий ключ добавляет с v |
добавит ключ |
update(other) |
добавляет и перезаписывает пары | добавит ключ |
pop(k, default) |
удаляет и возвращает значение | KeyError без default |
popitem() |
удаляет последнюю пару | KeyError на пустом словаре |
keys(), values(), items() |
ключи, значения, пары | ключ не передаётся |
copy() |
поверхностная копия | ключ не передаётся |
clear() |
удаляет всё | ключ не передаётся |
setdefault() не перезаписывает то, что уже есть:
stock = {"яблоки": 10}
stock.setdefault("груши", 0)
stock.setdefault("яблоки", 0)
print(stock)
Результат:
{'яблоки': 10, 'груши': 0}
Как перебрать словарь: keys, values, items

Цикл for по словарю идёт по ключам. Значение достаём по ключу внутри цикла:
week = {"Пн": 8, "Вт": 6, "Ср": 7}
for day in week:
print(day, week[day])
Результат:
Пн 8
Вт 6
Ср 7
Удобнее сразу брать пары через items(): ключ и значение распакуются в две переменные. values() отдаёт только значения, их можно сразу сложить.
week = {"Пн": 8, "Вт": 6, "Ср": 7}
for day, hours in week.items():
print(f"{day}: {hours} ч")
print(sum(week.values()))
print(list(week.keys()))
Результат:
Пн: 8 ч
Вт: 6 ч
Ср: 7 ч
21
['Пн', 'Вт', 'Ср']
Порядок обхода совпадает с порядком добавления. Это гарантировано начиная с Python 3.7, в 3.6 так работала только реализация CPython.
d = {"b": 2, "a": 1}
d["c"] = 3
print(list(d))
Результат:
['b', 'a', 'c']
Чтобы пройти словарь в другом порядке, например от большего значения к меньшему, передайте пары в sorted() с ключом сортировки. Как устроены sorted() и параметр key, разобрано в статье о сортировке в Python.
week = {"Пн": 8, "Вт": 6, "Ср": 7}
for day, hours in sorted(week.items(), key=lambda p: p[1], reverse=True):
print(day, hours)
Результат:
Пн 8
Ср 7
Вт 6
Номер элемента при переборе даст функция enumerate(): for i, (day, hours) in enumerate(week.items()).
Вложенные словари и подсчёт
Словарь словарей
Значением словаря может быть другой словарь. Так хранят карточки студентов, товаров, пользователей. Доступ идёт цепочкой ключей, а get() с пустым словарём по умолчанию спасает от ошибки на отсутствующей записи.
students = {
"Анна": {"group": "ПИ-21", "marks": [5, 4, 5]},
"Борис": {"group": "ПИ-22", "marks": [4, 4, 3]},
}
print(students["Анна"]["group"])
students["Борис"]["marks"].append(5)
print(students["Борис"])
print(students.get("Вера", {}).get("group", "нет такого студента"))
Результат:
ПИ-21
{'group': 'ПИ-22', 'marks': [4, 4, 3, 5]}
нет такого студента
Ровно такую структуру отдают почти все API и конфиги в формате JSON. Как сохранить вложенный словарь в файл, показано в инструкции про запись в JSON.
Подсчёт элементов
Типовая задача: сколько раз встречается каждое слово. Через get() с нулём по умолчанию это три строки:
text = "кот пёс кот рыба кот пёс"
counts = {}
for word in text.split():
counts[word] = counts.get(word, 0) + 1
print(counts)
Результат:
{'кот': 3, 'пёс': 2, 'рыба': 1}
Для группировки удобен defaultdict из модуля collections: отсутствующий ключ он создаёт сам, с пустым списком или нулём.
from collections import defaultdict
orders = [("Анна", "чай"), ("Борис", "кофе"), ("Анна", "сок")]
by_client = defaultdict(list)
for client, item in orders:
by_client[client].append(item)
print(dict(by_client))
Результат:
{'Анна': ['чай', 'сок'], 'Борис': ['кофе']}
А для подсчёта в стандартной библиотеке есть готовый Counter, это тоже подкласс словаря:
from collections import Counter
text = "кот пёс кот рыба кот пёс"
counts = Counter(text.split())
print(counts.most_common(2))
Результат:
[('кот', 3), ('пёс', 2)]
Частые ошибки и что с ними делать

Ошибка 1: KeyError на отсутствующем ключе
Симптом: программа падает на d["phone"]. Причина: такого ключа нет, а квадратные скобки не прощают.
Решение: d.get("phone"), проверка if "phone" in d или обработка исключения через try except, если ключ пропадает редко и это сбой.
Ошибка 2: удаление элементов прямо в цикле
Если удалять ключи прямо внутри for по словарю, цикл упадёт:
prices = {"хлеб": 60, "сыр": 450, "чай": 210}
for name in prices:
if prices[name] > 200:
del prices[name]
Результат:
RuntimeError: dictionary changed size during iteration
Решение: перебирайте копию ключей list(prices) или соберите новый словарь генератором.
prices = {"хлеб": 60, "сыр": 450, "чай": 210}
for name in list(prices):
if prices[name] > 200:
del prices[name]
print(prices)
cheap = {k: v for k, v in {"хлеб": 60, "сыр": 450}.items() if v <= 200}
print(cheap)
Результат:
{'хлеб': 60}
{'хлеб': 60}
Ошибка 3: fromkeys() с изменяемым значением
Все ключи получают один и тот же список, а не копии. В документации к fromkeys() это отмечено отдельно.
groups = dict.fromkeys(["А", "Б"], [])
groups["А"].append("Анна")
print(groups)
fixed = {name: [] for name in ["А", "Б"]}
fixed["А"].append("Анна")
print(fixed)
Результат:
{'А': ['Анна'], 'Б': ['Анна']}
{'А': ['Анна'], 'Б': []}
Решение: генератор словаря, он создаёт новый список для каждого ключа.
Ошибка 4: «копия», которая меняет оригинал
alias = original даёт тому же словарю второе имя, копии не появляется. copy() копирует только верхний уровень: вложенные списки остаются общими. Полную копию делает copy.deepcopy().
import copy
original = {"name": "Анна", "tags": ["python"]}
alias = original
alias["name"] = "Вера"
print(original["name"])
shallow = original.copy()
shallow["tags"].append("sql")
print(original["tags"])
deep = copy.deepcopy(original)
deep["tags"].append("git")
print(original["tags"])
Результат:
Вера
['python', 'sql']
['python', 'sql']
Ошибка 5: список в роли ключа
Симптом: TypeError с текстом про unhashable type. Причина: список изменяемый, ключом он быть не может.
Решение: tuple(ваш_список). Если внутри кортежа окажется список, ошибка повторится.
Где освоить Python системно
Словари встречаются почти в каждой программе: настройки, ответы сервера, подсчёты, группировки. Закрепить их удобнее на коротких упражнениях, например на 30 задачах для начинающих, а следующим шагом обычно идут классы и объекты.
Если нужна программа с наставником и проверкой домашних заданий, сравните курсы по Python в каталоге: там видны цена, длительность и формат у разных школ. Вот пять из них:
| Курс | Школа | Стоимость со скидкой | В рассрочку | Длительность | Обзор курса от Checkroi |
|---|---|---|---|---|---|
| Профессия «Python-разработчик» Перейти на сайт курса | 157 335 ₽ | 5987 ₽/мес. | 10 месяцев | Обзор курса | |
| Fullstack-разработчик на Python Перейти на сайт курса | 137 000 ₽ | 7125 ₽/мес. | 21 месяц | Обзор курса | |
| ДО Профессия Python-разработчик Перейти на сайт курса | 149 001 ₽ | 3167 ₽/мес. | 10 месяцев | Обзор курса | |
| Автоматизированное тестирование на Python Перейти на сайт курса | 118 754 ₽ | 4108 ₽/мес. | 9 месяцев | Обзор курса | |
| Профессия Python-разработчик Перейти на сайт курса | 140 040 ₽ | 3890 ₽/мес. | 10 месяцев | Обзор курса |
Больше программ — в полном каталоге курсов по Python




