问题描述
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 break
ing 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
),但并不可怕(只要您评论使用明确说明您打算使用redo
与continue
,以避免混淆维护人员.要允许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中的循环迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!