Перебирая список, но некоторые значения пропускаются...?
Перебор списка для удаления значений меньше целевого
Я пытаюсь перебрать numList и удалить все значения меньше 8 (цель). Оба 2 и 5 удаляются правильно, а 3 и 7 нет.
- Это определенно метод удаления. Если numList.remove(n) закомментирован, операторы печати программы работают правильно.
numList = [2, 3, 5, 7, 11, 13, 17, 19]
for n in numList:
print('Testing: {}'.format(n))
if n < 8:
print('-----REMOVING: {}'.format(n))
numList.remove(n)
ОЖИДАЕМЫЕ РЕЗУЛЬТАТЫ:
Тестирование: 2
----- УДАЛЕНИЕ: 2
Тестирование: 3
----- УДАЛЕНИЕ: 3
Тестирование: 5
----- УДАЛЕНИЕ: 5
Тестирование: 7
----- УДАЛЕНИЕ: 7
Тестирование: 11
Тестирование: 13
Тестирование: 17
Тестирование: 19
Ожидается: [11, 13, 17, 19]
ФАКТИЧЕСКИЕ РЕЗУЛЬТАТЫ
Тестирование: 2
----- УДАЛЕНИЕ: 2
Тестирование: 5
----- УДАЛЕНИЕ: 5
Тестирование: 11
Тестирование: 13
Тестирование: 17
Тестирование: 19
Актуально: [3, 7, 11, 13, 17, 19]
3 ответа
объяснение
Python начинает с создания списка индексов для циклического прохождения, а затем зацикливается как цикл for в C, но вы удаляете элементы из списка, пока он зацикливается.
В вашем списке 8 пунктов для начала, поэтому представьте, что Python внутренне решает, что он будет зацикливаться 8 раз, и каждый раз будет обращаться к элементу "i" в вашем списке.
[2, 3, 5, 7, 11, 13, 17, 19]
Сначала он обращается к первому элементу (который равен 2). Затем вы удалите 2, так что список теперь выглядит так
[3, 5, 7, 11, 13, 17, 19]
Теперь он получает доступ ко второму элементу (который равен 5).
Когда вы писали код, вы, возможно, ожидали, что второй элемент всегда будет считаться "3" при его циклическом прохождении.
Решение
Есть несколько способов справиться с этим. Одним из способов, который хорош с точки зрения Python, является использование синтаксиса понимания списка:
numList = [n for n in numList if n >= 8]
Если вы хотите, вам не нужно перезаписывать здесь numList, вместо этого вы можете присвоить правой стороне знака равенства новое имя списка.
Это потому, что вы удаляете из list
что вы перебираете.
Вам нужно сделать копию list
сначала перебираем это:
numList = [2, 3, 5, 7, 11, 13, 17, 19]
for n in numList[:]:
print('Testing: {}'.format(n))
if n < 8:
print('-----REMOVING: {}'.format(n))
numList.remove(n)
который дает:
Testing: 2
-----REMOVING: 2
Testing: 3
-----REMOVING: 3
Testing: 5
-----REMOVING: 5
Testing: 7
-----REMOVING: 7
Testing: 11
Testing: 13
Testing: 17
Testing: 19
Обратите внимание, что более Pythonic использовать list-comprehension
:
numList = [n for n in numList if n >= 8]
который дает:
[11, 13, 17, 19]
Никогда не меняйте размер списка, который вы повторяете. Лучше составьте новый список:
>>> numList = [2, 3, 5, 7, 11, 13, 17, 19]
>>> [x for x in numList if x >= 8]
[11, 13, 17, 19]