Рассмотрим этот код:
from random import randrange
from contextlib import suppress
mybiglist = [randrange(1, 100) for i in range(1000)]
count = 0
with suppress(ValueError):
while True:
mybiglist.remove(1)
count += 1
print("Count of 1's is : %d "% count)
Я не поставил никакого оператора break, чтобы закончить этот цикл. Я не могу понять, как и почему этот цикл «пока правда» завершается? Он волшебным образом прерывается, когда видит, что больше нет подходящих элементов для удаления! Как ?
Например:
from random import randrange
from contextlib import suppress
mybiglist = [randrange(1, 100) for i in range(1000)]
count = 0
with suppress(ValueError):
while True:
mybiglist.remove(222) # a number outside of the randrange, so zero occurrence
count += 1
print("Count of 222's is : %d "% count)
правильно печатает
Count of 222's is : 0
Учитывая, что счетчик даже не достиг значения «1», становится ясно, что list.remove() вызывает разрыв цикла while.
Но в документации для list.remove просто указано:
list.remove(x) : удалить из списка первый элемент, значение которого равно x. Он вызывает ValueError, если такого элемента нет.
и я уже подавил ValueError. Так что здесь происходит?
Следующий вариант без подавления работает должным образом и заканчивается бесконечным циклом.
from random import randrange
mybiglist = [randrange(1, 100) for i in range(1000)]
count = 0
while True:
try:
mybiglist.remove(222)
count += 1
except ValueError:
pass
print("Count of 222's is : %d "% count)
suppress
фактически перехватывает исключение после того, как он сломалwhile
, но вашtry, except
перехватывает исключение все еще внутриwhile
, поэтому он продолжается. - person quamrana   schedule 04.12.2019