能否“重新启动”Python循环的当前迭代?

16

有没有办法实现类似这样的东西:

for row in rows:
    try:
        something
    except:
        restart iteration

2
你可以跳到下一个迭代,但是你不能重试当前的迭代。 - Cory Kramer
是的,它被称为内部循环。 - Shashank
你的意思是像Perl中的redo吗?我认为Python中没有这样的东西。 - kratenko
1
我认为编程语言普遍应该添加能够回到同一次迭代的循环开始的功能(就像他们创造了continue和break一样,他们应该开发“reiterate”)。 - Eran Moshe
8个回答

26
你可以将 try/except 块放在另一个循环中,当它成功时跳出循环:
for row in rows:
    while True:
        try:
            something
            break
        except Exception: # Try to catch something more specific
            pass

“pass”不会导致for循环继续吗? - user3063864
1
不可以,因为它在 while 循环内部。代码将会从 except 块的末尾掉出,并回到 while 循环的顶部。请注意,如果需要的话,您也可以使用 continue。 - user2555451
那么我会在for循环的实际操作之前加入这个,它会一直运行,直到“某些东西”被确认通过,然后才运行我的for循环中的实际“某些东西”? - user3063864
是的,那是正确的。在上面的例子中,您将用要确认通过的代码替换 something。其余的代码将放在 while 循环下,直到 while 循环退出才会执行。 - user2555451
@Olaf - 在问题的标题中,OP说他想要重新启动当前迭代,而不是所有迭代。 - user2555451
显示剩余2条评论

6
你可以将行作为迭代器,在没有错误的情况下才推进。
it = iter(rows)  
row = next(it,"")
while row:
    try:
        something
        row = next(it,"")
    except:
       continue

顺便提一下,如果你还没有这样做的话,我建议在except中捕获特定的错误/异常,你不想抓取所有的错误。

如果你有虚假值,你可以将对象作为默认值:

it = iter(rows)
row, at_end = next(it,""), object()
while row is not at_end:
    try:
        something
        row = next(it, at_end)
    except:
        continue

1
这对我来说比while True:的答案更清晰。 - kratenko

3
虽然我不建议这样做,但唯一的方法是使用 While (True) 循环,直到完成 something。请注意可能出现无限循环的情况。
for row in rows:
    try:
        something
    except:
        flag = False
        while not flag:
            try: 
               something
               flag = True
            except:
               pass

1

将您的for循环放在一个无限的while循环内。使用if else条件检查您想要重新启动for循环的条件,并中断内部循环。在for循环之外的while循环内有一个if条件来中断while循环。 像这样:

    while True:
      for row in rows:
        if(condition)
        .....
        if(condition)
         break
   if(condition)
     break

1
这是一个简单的版本,不使用嵌套循环、无限循环或改变原始迭代器。此外,它通过一个max_retry参数来控制尝试次数。
def do_something(retry=0, max_retry=4):
    print(f"retry: {retry}, max_retry: {max_retry}")
    try:
        raise Exception
    except Exception as e:
        if retry == max_retry:
            print(f"Max retries reached!")
        else:
            do_something(retry=retry + 1)

do_something()

0

试试这个

it = iter(rows)
while True:
    try:
        something
        row = next(it)        
    except StopIteration:
        it = iter(rows)

0

我的意见是,如果rows是一个列表,你可以这样做

for row in rows:
    try:
        something
    except:
        # Let's restart the current iteration
        rows.insert(rows.index(row), row)
        continue  # <-- will skip `something_else`, i.e will restart the loop.

    something_else
    

此外,其他条件相同时,Python 中的 for 循环比 while 循环更快。话虽如此,在 Python 中,性能并不是第一顺位的决定因素。


0

我认为user2555451的回答已经很好了。话虽如此,你应该使用continue而不是pass,因为它会确保while True循环重新启动。

for row in rows:
    while True:
        try:
            ...
            break
        except Exception:
            continue

我会为新手Python用户解释一下: < p> break 仅中断您正在使用的循环。 因此,如果您有像这样的东西:(变量和函数是虚构的)
for x in imgWidth:
    for y in imgHeight:
         if ...:
             break
         drawPixel(x, y, "#FF0000")

如果你想跳过一个像素,可以使用break来退出循环并返回到上一级。同样的,continue也是如此。
现在回到例子:
for row in rows:
    while True:
        try:
            ...
            break
        except Exception:
            continue

将您想要运行的任何代码移动到try块内。它会尝试执行,如果捕获到错误,它将重试,因为我们使用continue继续while True循环!当最终无错误地执行代码时,它会break并回到for循环中。然后,它会继续下一次迭代,因为没有剩余任务可做。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接