Кот-наставник— Привет! Я кот-наставник, провожу людей через Python на платформе SkillPy. Списки ты уже знаешь — там всё по номерам. Словари устроены удобнее: доступ не по индексу, а по понятному ключу.
— Это как картотека: не «карточка №5», а «карточка на имя Анна». Разберёмся, как это работает.
Словари в Python (тип dict) — это коллекции пар «ключ — значение». Если список хранит элементы по номерам-индексам, то словарь хранит значения по осмысленным ключам: имя, артикул, город. В этом гайде разберём словари с нуля: создание, чтение через [] и .get(), добавление и удаление, методы keys(), values(), items(), перебор в цикле, вложенные словари и частую ошибку KeyError. Все примеры запускаются в Python 3.12 без библиотек.
Словарь в Python: коротко
Словарь — это набор пар «ключ: значение» в фигурных скобках. Значение достают по ключу, а не по номеру. Ключи уникальны. Минимальный пример:
user = {"name": "Анна", "age": 25} # создали словарь
print(user["name"]) # доступ по ключу → Анна
user["city"] = "Москва" # добавили новую паруАнна
Зачем нужны словари в Python
Представь, что хранишь данные пользователя в списке: ["Анна", 25, "Москва"]. Чтобы получить город, нужно помнить, что он под индексом 2. А если порядок изменится — код сломается. Со словарём такой проблемы нет: у каждого значения понятное имя-ключ.
# Список: значения по номерам — надо помнить порядок
user_list = ["Анна", 25, "Москва"]
print(user_list[2]) # что под индексом 2? приходится вспоминать
# Словарь: значения по ключам — код сам себя объясняет
user_dict = {"name": "Анна", "age": 25, "city": "Москва"}
print(user_dict["city"]) # сразу понятно, что берёмМосква Москва
Результат одинаковый, но user_dict["city"] читается однозначно, а user_list[2] требует помнить структуру. Про списки и доступ по индексу — в гайде Списки в Python: создание, методы и срезы.
Словарь (`dict`) — это изменяемая коллекция пар «ключ — значение». Ключи уникальны и неизменяемы (строки, числа, кортежи), значения — любые. Доступ к значению выполняется по ключу за одно действие, без перебора.
Создание словаря
Словарь создают в фигурных скобках {}, перечисляя пары ключ: значение через запятую. Пустой словарь — это просто {}.
# Словарь с данными
product = {"name": "Кофе", "price": 300, "in_stock": True}
# Пустой словарь — заполним позже
cart = {}
print(product)
print(cart){'name': 'Кофе', 'price': 300, 'in_stock': True}
{}Чтение по ключу и KeyError
Чтобы получить значение, указывают ключ в квадратных скобках. Например, в словаре с весом котов запись weights["Мурка"] вернёт 3.8. Это главное отличие от списка — там в скобках номер, здесь осмысленный ключ.
weights = {"Барсик": 4.5, "Мурка": 3.8, "Рыжик": 5.2}
print(weights["Мурка"])
print(weights["Рыжик"])3.8 5.2
weights = {"Барсик": 4.5, "Мурка": 3.8, "Рыжик": 5.2}
print(weights["Пушок"])Ошибка выполнения — main.py, строка 2
KeyError: 'Пушок'
Безопасное чтение через .get()
Теперь возьмём словарь товара и посмотрим, как безопасно читать необязательные поля. Чтобы не ловить KeyError, используют метод .get(): если ключа нет, он вернёт None (или значение по умолчанию, если его указать), а не обрушит программу.
product = {"name": "Кофе", "price": 300}
print(product.get("color")) # ключа нет → None
print(product.get("color", "не указан")) # ключа нет → значение по умолчанию
print(product.get("name")) # ключ есть → значениеNone не указан Кофе
Квадратные скобки или .get()?
Переключи ключ и сравни, что вернут оба способа
product = {"name": "Кофе", "price": 300}| Способ | Ключ существует: "name" | Ключ отсутствует: "color" |
|---|---|---|
| [] — строгий доступ | product["name"] → "Кофе"Ключ найден: возвращено значение. | product["color"] → KeyError: 'color'Ключ отсутствует: возникло исключение KeyError. |
| .get() — безопасное чтение | product.get("name") → "Кофе"Ключ найден: возвращено значение. | product.get("color") → NoneКлюч отсутствует: возвращено None, исключения нет. Можно задать значение по умолчанию: product.get("color", "не указан") → "не указан" |
Ключ есть: оба способа дали одинаковый результат
Ключа нет: [] сообщает об ошибке, .get() позволяет обработать отсутствие
[] нужен, когда ключ обязан существовать: нарушение контракта заметно сразу. .get() подходит, когда отсутствие ключа ожидаемо и его нужно обработать.
Кот-наставник— Простое правило: если ключ точно должен быть — бери
[], пусть падает громко при ошибке в данных. Если ключа может не быть — бери.get()с понятным значением по умолчанию.
Добавление и изменение значений
Присваивание по ключу работает и на добавление, и на изменение. Если ключа нет — создаётся новая пара. Если есть — значение перезаписывается.
user = {"name": "Анна"}
user["age"] = 25 # ключа нет → добавили пару
user["name"] = "Аня" # ключ есть → изменили значение
print(user){'name': 'Аня', 'age': 25}Проверка ключа: оператор in
Перед обращением к ключу можно проверить, есть ли он в словаре, — через оператор in. Это ещё один способ избежать KeyError.
user = {"name": "Анна", "age": 25}
print("name" in user)
print("email" in user)
if "email" not in user:
print("Почта не указана")True False Почта не указана
Методы keys(), values() и items()
Три метода дают доступ к содержимому словаря: keys() — все ключи, values() — все значения, items() — пары «ключ-значение». Чаще всего они нужны для перебора.
Методы доступа к содержимому
| Метод | Что возвращает | Пример результата |
|---|---|---|
| .keys() | все ключи | ['name', 'age'] |
| .values() | все значения | ['Анна', 25] |
| .items() | пары «ключ-значение» | [('name', 'Анна'), ('age', 25)] |
| .get(key) | значение или None | 'Анна' или None |
user = {"name": "Анна", "age": 25}
print(list(user.keys()))
print(list(user.values()))
print(list(user.items()))['name', 'age']
['Анна', 25]
[('name', 'Анна'), ('age', 25)]Перебор словаря в цикле
Чаще всего словарь перебирают циклом for через .items() — так на каждом шаге доступны и ключ, и значение сразу.
prices = {"Кофе": 300, "Чай": 200, "Круассан": 90}
for name, price in prices.items():
print(f"{name}: {price} руб.")Кофе: 300 руб. Чай: 200 руб. Круассан: 90 руб.
Если перебирать словарь напрямую (for key in prices), в переменную попадут только ключи — значение нужно будет доставать отдельно. Поэтому .items() удобнее. Подробно про цикл for и перебор коллекций — в гайде Циклы в Python: for, while, break и continue.
Удаление элементов: del и pop()
Удалить пару можно оператором del или методом .pop(). Разница в том, что .pop() ещё и возвращает удалённое значение.
user = {"name": "Анна", "age": 25, "city": "Москва"}
del user["city"] # просто удалить
age = user.pop("age") # удалить и вернуть значение
print(user)
print(f"Удалённый возраст: {age}"){'name': 'Анна'}
Удалённый возраст: 25Вложенные словари
Значением в словаре может быть другой словарь — так хранят структурированные данные, например профили нескольких пользователей. Доступ к вложенным данным — через несколько ключей подряд.
users = {
"anna": {"age": 25, "city": "Москва"},
"oleg": {"age": 32, "city": "Казань"},
}
print(users["anna"]["city"])
print(users["oleg"]["age"])Москва 32
users["anna"] возвращает вложенный словарь, а второй ключ ["city"] достаёт из него значение. Так можно углубляться на сколько нужно уровней.
Словарь или список: что выбрать
Списки и словари решают разные задачи. Список — когда важен порядок и элементы однородны (список цен, имён). Словарь — когда у каждого значения своё имя и нужен быстрый доступ по нему.
| Критерий | Список | Словарь |
|---|---|---|
| Доступ к элементу | по индексу: data[0] | по ключу: data["name"] |
| Что хранит | упорядоченную последовательность | пары «ключ — значение» |
| Когда использовать | однородные данные, важен порядок | данные с именами, быстрый поиск |
| Поиск значения | перебором | сразу по ключу |
Частые ошибки со словарями
- KeyError при обращении к несуществующему ключу
Самая частая ошибка — чтение по ключу, которого нет. Если ключ может отсутствовать, используй
.get()или проверку черезin, а не[]. - Ключом может быть не любой объект
Ключи должны быть неизменяемыми: строки, числа, кортежи. Список ключом быть не может — попытка даст
TypeError: unhashable type: 'list'. Про изменяемые и неизменяемые типы — в гайде Типы данных в Python: полный гайд для начинающих. - Дубликаты ключей молча теряются
Если задать один ключ дважды, останется только последнее значение — без ошибки.
{"a": 1, "a": 2}превратится в{"a": 2}. Ключи в словаре уникальны по определению.
Короткие ответы на вопросы про словари
Чем словарь отличается от списка?
В списке доступ к элементам по числовому индексу и важен порядок, в словаре — по осмысленному ключу. Словарь удобнее, когда у каждого значения есть имя и нужен быстрый доступ по нему.
Как безопасно получить значение из словаря?
Через метод .get(key): если ключа нет, он вернёт None вместо ошибки KeyError. Можно задать значение по умолчанию: .get(key, "нет").
Что может быть ключом словаря?
Любой неизменяемый объект: строка, число, кортеж. Изменяемые объекты (список, другой словарь) ключом быть не могут — Python выдаст TypeError.
Как перебрать словарь?
Циклом for через .items(): for key, value in d.items():. Так на каждом шаге доступны и ключ, и значение. Через .keys() переберёшь только ключи, через .values() — только значения.
Главное про словари:
- Словарь — пары «ключ — значение»
Создаётся в
{}, доступ по ключу, а не по индексу.user = {"name": "Анна", "age": 25} print(user["name"]) # Анна .get()защищает от KeyErrorВозвращает
Noneили значение по умолчанию, если ключа нет.user.get("email", "не указан")- Добавление и изменение — через присваивание по ключу
user["city"] = "Москва" # добавили user["age"] = 26 # изменили - Перебор — через
.items()for key, value in user.items(): print(key, value) - Ключи уникальны и неизменяемы
Строки, числа, кортежи — можно; списки — нельзя.
Кот-наставник— Словарь — это про смысл вместо номеров. Как только данных становится больше двух-трёх значений, спрашивай себя: а не дать ли им имена-ключи?
— Напиши свой словарь, достань значение по ключу, потом обратись к несуществующему — поймай
KeyErrorсвоими глазами. Так запомнится лучше, чем любой текст.
Словари усваиваются, когда пишешь их сам
На SkillPy ты создаёшь словари, читаешь по ключу и ловишь KeyError в безопасной среде, а AI-наставник объясняет, почему упало и когда брать .get() вместо []. Он понимает твой код, а не сверяет с шаблоном.
