← Все вопросы

Список меняется прямо в цикле for, и часть элементов пропускается

Задан 7 месяцев назад738 просмотров2 ответа
8

Хочу удалить из списка все нули, но что-то остаётся:

nums = [0, 0, 1, 0, 2]
for x in nums:
    if x == 0:
        nums.remove(x)
print(nums)  # [0, 1, 2]  — один ноль остался!

Почему один ноль не удалился?

2 ответа

14
✓ Принятый ответ — помог автору

Нельзя менять список, по которому идёшь в цикле. Когда ты удаляешь элемент, остальные сдвигаются влево, а внутренний счётчик цикла продолжает расти — и он перепрыгивает через соседний элемент. Поэтому второй подряд ноль остаётся незамеченным.

Правильно — строить новый список (фильтрацией), не трогая исходный во время обхода:

nums = [0, 0, 1, 0, 2]
nums = [x for x in nums if x != 0]
print(nums)  # [1, 2]

Это и короче, и безопаснее.

5

Если очень нужно именно удалять на месте — иди по копии: for x in nums[:]:. Тогда цикл проходит по копии, а изменения вносятся в оригинал, и сдвиг ничего не ломает.

Ваш ответ

Войдите, чтобы ответить на вопрос.