Что такое словарь (dict) в Python
Что проверяют
Базовый вопрос, по которому смотрят, знаете ли вы не только синтаксис, но и устройство: сложность операций, требования к ключу, поведение порядка.
Как отвечать
dict это хеш-таблица, отображение ключей в значения. Ключевые свойства:
- доступ, вставка и удаление в среднем за O(1), в худшем случае хуже, но это редкость;
- ключ должен быть хешируемым: числа, строки, кортежи из хешируемых элементов,
frozenset, объекты пользовательских классов. Списки и множества ключами быть не могут; - порядок вставки сохраняется: это деталь реализации в CPython 3.6 и часть языка начиная с 3.7. Поэтому
OrderedDictсегодня нужен редко, в основном радиmove_to_endи сравнения с учётом порядка; - значения любые, ключи уникальны, повторная запись перезаписывает значение.
Полезно показать рабочие приёмы, а не только d[key]:
d.get("key", 0) # без KeyError
d.setdefault("items", []).append(x)
{k: v for k, v in pairs if v} # словарное включение
merged = base | override # объединение, Python 3.9+
for k, v in d.items(): ...Из стандартной библиотеки рядом стоит назвать collections.defaultdict (значение по умолчанию для отсутствующего ключа), Counter (подсчёт частот) и dict.fromkeys для быстрой заготовки. Уместно упомянуть цену: словарь тратит заметно больше памяти, чем список той же длины, и на больших объёмах однотипных записей выбирают dataclass со __slots__, кортежи или массивы.
Где спотыкаются
Обращаются по отсутствующему ключу и ловят KeyError там, где нужен get.
Используют изменяемый объект как значение по умолчанию в аргументе функции и получают общий словарь на все вызовы.
Меняют размер словаря во время итерации: RuntimeError: dictionary changed size during iteration. Нужно обходить копию ключей.
Считают, что dict потокобезопасен целиком. Отдельные операции атомарны, но составные последовательности нет.