d = {"a": 1, "b": 2}
for k in list(d.keys()):
del d[k]
print(d)
Данный код демонстрирует проблему изменения словаря во время итерации по его ключам. Он приводит к ошибке RuntimeError: dictionary changed size during iteration в версиях Python до 3.7. В Python 3.7+ итерирование ведёт себя по другому, но итоговый словарь будет отличаться от ожидаемого.
d = {"a": 1, "b": 2}: Инициализируется словарь d с двумя ключами: "a" и "b".for k in list(d.keys()):: Создается список ключей словаря. d.keys() возвращает представление ключей, которое затем преобразуется в список ['a', 'b']. Затем происходит итерация по этому списку.k = 'a': del d['a'] удаляет ключ "a" из словаря. Теперь словарь d становится {"b": 2}.k = 'b': del d['b'] удаляет ключ "b" из словаря. Теперь словарь d становится {} (пустым).print(d): Выводит пустой словарь {}.В версиях Python до 3.7, изменение размера словаря во время итерации по его ключам приводило к ошибке. Это происходило потому, что итератор словаря "запоминал" размер словаря в момент начала итерации, и при изменении этого размера итератор становился недействительным.
Чтобы избежать этой ошибки, можно использовать разные подходы:
d = {"a": 1, "b": 2}
new_d = {}
for k, v in d.items():
# здесь можно проверить, нужно ли оставлять элемент
# если да, то добавить его в new_d
pass # Заглушка, чтобы код был рабочим
d = new_d # заменили старый словарь новым
print(d)
d = {"a": 1, "b": 2}
new_d = {k: v for k, v in d.items() if False} # Все ключи отфильтрованы
d = new_d # заменили старый словарь новым
print(d)
list(d.keys())), чтобы обезопасить себя от изменений размера словаря:
d = {"a": 1, "b": 2}
for k in list(d.keys()): # итерируемся по копии ключей
del d[k]
print(d)
В данном конкретном случае этот код работает и в более старых версиях, но **не рекомендуется** для более сложных сценариев, где условия удаления зависят от других ключей, так как порядок итерации не гарантируется.
В Python 3.7+ код выполнится без ошибок и выведет {}. В версиях Python до 3.7 код выбросит исключение RuntimeError: dictionary changed size during iteration.