Программирование и IT
Python: словари
Словарь хранит пары «ключ — значение» и находит значение по ключу за постоянное время независимо от размера. Это рабочая лошадка для подсчётов, группировок и настроек. Разберём создание, безопасный доступ, перебор и места, где словарь ведёт себя не так, как ожидают.
В этой статье
Создание и требования к ключу#
=
= # именно словарь, а не множество
=
# 120 2
Ключом может быть только неизменяемое значение: строка, число, кортеж,
логическое. Список ключом быть не может — попытка даёт TypeError: unhashable type: 'list'. Значением может быть что угодно, включая другой словарь.
Порядок вставки сохраняется: начиная с Python 3.7 это не случайность
реализации, а гарантия языка. Перебор словаря даёт ключи в том порядке, в
котором их добавляли.
Доступ без KeyError#
Квадратные скобки при отсутствии ключа бросают KeyError. Когда отсутствие
ключа — нормальная ситуация, берут get:
# None
# 0
# False
= 90 # добавление — тоже через скобки
Оператор in проверяет именно ключи, а не значения; для значений нужен
in prices.values().
Родственный метод setdefault возвращает значение по ключу, а если ключа нет —
кладёт указанное и возвращает его. Это удобно для группировки:
=
# {'е': ['ель'], 'ё': ['ёж'], 'с': ['сосна', 'сова']}
Перебор и три представления#
# ['чай', 'кофе', 'какао']
# 460
keys(), values() и items() возвращают не списки, а представления: они
«смотрят» на живой словарь и отражают изменения. Если нужен именно список —
оберни в list().
Сортировка словаря даёт список пар, а не словарь:
=
# [('кофе', 250), ('чай', 120), ('какао', 90)]
# обратно в словарь, если нужен словарь
Изменение, удаление, слияние#
# {'чай': 130, 'кофе': 250, 'какао': 90, 'сок': 100}
=
# 90
# 0 вместо KeyError
del
update перезаписывает существующие ключи и добавляет новые. С Python 3.9 есть
оператор слияния: a | b даёт новый словарь, а a |= b меняет a на месте.
При совпадении ключа побеждает правый словарь.
Словарное выражение строится как списочное, но с парой через двоеточие:
=
# {0: 0, 1: 1, 2: 4, 3: 9}
=
# 3
Где ломается#
Добавление во время перебора. Изменение размера словаря внутри цикла по
нему даёт RuntimeError: dictionary changed size during iteration. Собирай
изменения отдельно или перебирай копию: for k in list(d).
Одинаковые ключи в литерале. {"a": 1, "a": 2} — не ошибка, останется
{'a': 2}: последнее присваивание побеждает молча.
True и 1 — один ключ. Ключи сравниваются по значению, а 1 == True,
поэтому {1: "раз", True: "да"} схлопнется в один элемент со значением "да".
Подсчёт через get. Типичная задача — частоты. Без словаря она разрастается
в десяток строк, а так укладывается в три:
=
= + 1
# {'а': 5, 'б': 2, 'р': 2, 'к': 1, 'д': 1}
Попробуй сам: посчитай частоты слов в тексте и выведи три самых частых
через sorted с key. Для работы с текстом пригодятся
строки, а когда порядок важнее ключей —
списки.
План по этапам
- Словарь настроекСоздать словарь из пяти пар, вывести значение по ключу и длину.
- Безопасный доступСравнить d["нет"] и d.get("нет", 0): первый вызов должен дать KeyError.
- Перебор itemsВывести все пары в формате «ключ → значение» через items().
- Частоты символовПосчитать, сколько раз каждый символ встречается в строке, через get.
- Сортировка по значениюОтсортировать пары по убыванию значения и вывести первые три.
Начать изучать эту тему у себя
План ляжет в твой репозиторий: отмечай этапы, веди конспект — история изменений покажет, как ты продвинулся.
Проверь себя
1.Что выведет: d = {"a": 1}; print(d.get("b", 0))?
2.Что выведет print(len({"a": 1, "b": 2, "a": 3}))?
3.Что выведет: d = {"x": 1}; print("x" in d, 1 in d)?
4.Сколько раз буква «а» встречается в строке «абракадабра»?
Источники
-
Словари в учебнике PythonРаздел Dictionaries с примерами переборабесплатно
-
Справочник типа dictВсе методы словаря и правила для ключейбесплатно
-
StepikЗадачи на словари с автопроверкойбесплатно
Было полезно?