重做Python中的循环迭代 [英] Redo for loop iteration in Python

查看:76
本文介绍了重做Python中的循环迭代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Python是否具有某些语言中存在的重做"语句形式的任何内容?

Does Python have anything in the fashion of a "redo" statement that exists in some languages?

("redo"语句是一条语句(就像"break"或"continue"一样)会影响循环行为-它会在最内层循环的开始处跳转并再次开始执行.)

(The "redo" statement is a statement that (just like "break" or "continue") affects looping behaviour - it jumps at the beginning of innermost loop and starts executing it again.)

推荐答案

否,Python不直接支持redo.一种选择可能会使涉及嵌套循环的事情变得非常可怕,例如:

No, Python doesn't have direct support for redo. One option would something faintly terrible involving nested loops like:

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

但这意味着在没有redo -able块的情况下,break不可能在不使用异常,标志变量或将整个函数包装为一个函数的情况下在"redo -able"块中进行.

but this mean that breaking the outer loop is impossible within the "redo-able" block without resorting to exceptions, flag variables, or packaging the whole thing up as a function.

或者,您使用直接的while循环,该循环复制for循环为您执行的操作,显式创建和推进迭代器.它有其自身的问题(默认情况下,continue实际上是redo,您必须显式地将迭代器推进为真实的" continue),但并不可怕(只要您评论使用明确说明您打算使用redocontinue,以避免混淆维护人员.要允许redo和其他循环操作,您可以执行以下操作:

Alternatively, you use a straight while loop that replicates what for loops do for you, explicitly creating and advancing the iterator. It has its own issues (continue is effectively redo by default, you have to explicitly advance the iterator for a "real" continue), but they're not terrible (as long as you comment uses of continue to make it clear you intend redo vs. continue, to avoid confusing maintainers). To allow redo and the other loop operations, you'd do something like:

# 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)

上面的操作也可以用try/except StopIteration:代替带有sentinel的两个参数next,但是用它包裹整个循环可能会导致捕获其他StopIteration源,并且在内部和外部next调用中在有限范围内正确执行此操作将非常难看(比基于sentinel的方法要差得多).

The above could also be done with a try/except StopIteration: instead of two-arg next with a sentinel, but wrapping the whole loop with it risks other sources of StopIteration being caught, and doing it at a limited scope properly for both inner and outer next calls would be extremely ugly (much worse than the sentinel based approach).

这篇关于重做Python中的循环迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆