Можно ли сохранить ключи словаря в список, удалить их из словаря и потом обновить словарь
Что проверяют
Понимаете ли вы, что .keys() возвращает динамическое представление, а не копию, и знаете ли, почему изменение словаря во время итерации приводит к ошибке. Вопрос простой, но ответ сразу показывает степень знакомства с коллекциями.
Как отвечать
Да, вся последовательность рабочая, если снять снимок ключей:
d = {"a": 1, "b": 2, "c": 3}
keys = list(d)
for k in keys:
d.pop(k, None)
d.update({"d": 4, "a": 10})Существенные детали:
d.keys()это представление, связанное со словарём: оно меняется вместе с ним и поддерживает операции множеств.list(d)даёт независимый список, поэтому цикл выше безопасен;- итерация напрямую по словарю с удалением внутри даёт RuntimeError про изменение размера во время обхода;
del d[k]бросает KeyError на отсутствующем ключе,d.pop(k, None)нет, а очистить всё проще черезd.clear();- обновление:
d.update(other)иd |= otherменяют словарь на месте,d | otherвозвращает новый; - порядок вставки сохраняется, поэтому после очистки ключи встанут в новом порядке, а не в исходном.
Где спотыкаются
Фильтруют словарь циклом прямо по нему и ловят RuntimeError. Правильных путей два: обойти снимок из list(d) либо собрать новый словарь включением по d.items().
Считают представление копией. Сохранили ссылку на d.keys(), поменяли словарь и удивляются, что сохранённое изменилось само по себе.
Внутри функции присваивают параметру новый словарь и ждут, что изменится исходный. Присваивание лишь переставляет локальное имя, вызывающему этого не видно. Менять надо сам объект: через clear, update или удаление ключей.