重做Python中的循环迭代

Mat*_*dis 13 python for-loop redo python-2.7

Python是否有某些语言中存在的"重做"语句?

("重做"语句是一个声明(就像"break"或"continue")影响循环行为 - 它在最内层循环的开头跳转并再次开始执行它.)

cma*_*ard 6

不,它没有.我建议使用while循环并将check变量重置为初始值.

count = 0
reset = 0
while count < 9:
   print 'The count is:', count
   if not someResetCondition:
       count = count + 1
Run Code Online (Sandbox Code Playgroud)


Sha*_*ger 5

不,Python不直接支持redo。一种选择是涉及嵌套循环的可怕的事情,例如:

for x in mylist:
    while True:
        ...
        if shouldredo:
            continue  # continue becomes equivalent to redo
        ...
        if shouldcontinue:
            break     # break now equivalent to continue on outer "real" loop
        ...
        break  # Terminate inner loop any time we don't redo
Run Code Online (Sandbox Code Playgroud)

但这意味着breakredo不使用异常,标志变量或将整个函数包装为一个函数的情况下,不可能在“ -able”块内进行外循环。

另外,您可以使用一个直接while循环来复制for循环为您执行的操作,从而显式创建和推进迭代器。它有其自身的问题(默认情况下continue实际上是有效redo的,您必须显式地将迭代器推进为“ real” continue),但是它们并不可怕(只要您对的用法进行评论continue以明确表示您打算redocontinue,以避免)令人困惑的维护者)。要允许redo和其他循环操作,您需要执行以下操作:

# Create guaranteed unique sentinel (can't use None since iterator might produce None)
sentinel = object()
iterobj = iter(mylist)  # Explicitly get iterator from iterable (for does this implicitly)
x = next(iterobj, sentinel)  # Get next object or sentinel
while x is not sentinel:     # Keep going until we exhaust iterator
    ...
    if shouldredo:
        continue
    ...
    if shouldcontinue:
        x = next(iterobj, sentinel)  # Explicitly advance loop for continue case
        continue
    ...
    if shouldbreak:
        break
    ...
    # Advance loop
    x = next(iterobj, sentinel)
Run Code Online (Sandbox Code Playgroud)

上面的代码也可以用try/ except StopIteration:而不是next带有-arg的two-arg 来完成sentinel,但是用它包装整个循环可能会导致其他来源StopIteration被捕获,并且在有限的范围内对内部next调用和外部调用都这样做是非常丑陋的(比sentinel基础方法差很多)。