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
.