此“ while True”循环如何结束?

时间:2019-12-04 16:28:35

标签: python python-3.x list suppress

考虑以下代码:

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语句来结束此循环。 我无法理解此“ while True”循环如何以及为什么终止? 当发现没有其他要删除的匹配元素时,它会神奇地中断! 怎么样?

例如:

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)

2 个答案:

答案 0 :(得分:4)

删除不存在的元素会引发错误。该错误将停止循环,并且由于您在外部抑制了该循环,因此抑制后的代码将继续:

with suppress(ValueError):
    while True:
        mybiglist.remove(222) # element that doesn't exist, raises error
        count += 1
# ... code continues here

如果希望循环继续进行,则必须在错误传播到循环之前抑制该错误:

while True:
    with suppress(ValueError):
        mybiglist.remove(222) # element that doesn't exist, raises error
        count += 1
    # ... code continues here

这意味着即使出现错误,循环也将继续运行。

答案 1 :(得分:0)

您的代码抑制了结束循环的错误。您的循环最终无法从biglist中删除另一个值,并抛出您已抑制的ValueError,因此循环对您而言似乎是干净的结束。如果删除with suppress(ValueError):,则会看到以下内容:ValueError: list.remove(x): x not in list