【问题标题】:How does this "while True" loop end?这个“while True”循环如何结束?
【发布时间】:2019-12-04 16:28:35
【问题描述】:

考虑这段代码:

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)

【问题讨论】:

  • suppress 在破坏while 后实际上会捕获异常,但您的try, except 仍会在while 内捕获异常,因此它会继续。

标签: python python-3.x list suppress


【解决方案1】:

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2020-05-31
      • 2017-08-31
      • 2019-03-15
      • 2013-05-14
      • 1970-01-01
      • 2017-04-18
      • 1970-01-01
      • 2022-01-23
      • 2020-01-17
      相关资源
      最近更新 更多