Какие методы словарей Python используются для удаления ключей?
Что проверяют
Знаете ли вы разницу между способами удаления и их поведение на отсутствующем ключе. Вопрос разминочный, поэтому следом почти наверняка спросят, как удалить ключи во время обхода словаря.
Как отвечать
Инструментов пять, у каждого своя роль:
del d[key]: инструкция языка, а не метод. Ничего не возвращает, на отсутствующем ключе бросаетKeyError;d.pop(key): удаляет и возвращает значение, без ключа тожеKeyError. С дефолтомd.pop(key, None)ошибки не будет, это самый короткий способ удалить ключ, если он есть;d.popitem(): удаляет и возвращает пару(key, value). С Python 3.7 порядок работы гарантирован: это стек, забирается последняя вставленная пара. На пустом словареKeyError;d.clear(): очищает словарь на месте, и все ссылки на этот объект увидят пустой словарь. Присваиваниеd = {}так не работает, оно лишь перепривязывает имя;- генератор словаря:
{k: v for k, v in d.items() if k not in to_drop}строит новый словарь без лишних ключей. Формально это не удаление, но часто лучший вариант.
Сравните d.pop(key, None) и if key in d: del d[key]: результат одинаковый, но первый вариант ищет ключ один раз. Если нужна очередь с обеих сторон, у collections.OrderedDict есть popitem(last=False), который забирает первую пару, и move_to_end.
Заметка про память: CPython не уменьшает таблицу словаря при удалении, освободившиеся слоты ждут перестройки при будущих вставках. После массовой чистки большого словаря выгоднее собрать новый.
Где спотыкаются
Удаляют ключи прямо в цикле for k in d: и получают RuntimeError: dictionary changed size during iteration. Обходите копию list(d) или соберите новый словарь.
Называют del методом словаря. Это инструкция, она работает и с элементами списков, и с атрибутами, и с именами.
Говорят, что popitem удаляет случайный элемент. Так было до Python 3.7, сейчас он предсказуемо берёт последний вставленный.