Не меняй список во время прохода по нему.
Когда ты модифицируешь список прямо во время итерации, итератор начинает путаться. Он не “знает”, что список изменился прямо у него под ногами.
Например, этот код сломан:
items = [1, 2, 2, 3, 4]
for item in items:
if item == 2:
items.remove(item)
print(items)
# Output: [1, 2, 3, 4]
Здесь мы используем
remove(), чтобы удалить все двойки из списка. Но если посмотреть на вывод, одна 2 все равно осталась. Почему так происходит: когда ты удаляешь элемент из списка, все элементы справа сдвигаются влево. А цикл продолжает идти дальше. В итоге происходит вот что: находится и удаляется первая 2. Вторая 2 сдвигается на ее место. Цикл переходит к следующему индексу и пропускает эту 2.Лучший способ сделать это: итерироваться по копии:
for item in items[:]:
if item == 2:
items.remove(item)
print(items)
# Output: [1, 3, 4]
Когда ты проходишь по копии (поверхностной копии), индексы в исходной копии не меняются.
Еще лучше использовать list comprehension:
items = [x for x in items if x != 2]
Никогда, ни при каких условиях не модифицируй список (или любую коллекцию) прямо во время итерации по нему. Итератор плохо переносит структурные изменения: он может пропускать элементы, обрабатывать один и тот же элемент дважды или (в некоторых случаях, например со словарями) выбрасывать
RuntimeError. Это плохая практика.👉 @PythonPortal
