user3063864
user3063864

Reputation: 721

Can you "restart" the current iteration of a Python loop?

Is there a way to implement something like this:

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

Upvotes: 20

Views: 24883

Answers (8)

nocibambi
nocibambi

Reputation: 2421

Here is a simple version without using nested loops, an infinite while loop, or mutating the original iterator. Also, it controls the number of attempts with a max_retry parameter:

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

Upvotes: 0

roundabout
roundabout

Reputation: 321

I think user2555451's answer does it pretty well. That being said, you should use continue instead of pass as it will make sure the while True loop is restarted.

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

I will explain it for newer Python users:

break only breaks the loop you're working in. So if you have something like this: (the variables and functions are imaginary)

for x in imgWidth:
    for y in imgHeight:
         if ...:
             break
         drawPixel(x, y, "#FF0000")

and you somehow want to skip a pixel, you can break the loop as it will return to the previous level. The same is true for continue.

Now back to the example:

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

You move any code you would like to run inside the try block. It will try to do it, and if it catches an error, it will retry because we continue the while True loop! When it finally does the code without errors, it breaks and now it's back in the for loop. Then it continues to the next iteration as it has nothing left to do.

Upvotes: 0

keepAlive
keepAlive

Reputation: 6655

My 2¢, if rows is a list, you could do

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
    

Also, other things being equal, for-loops are faster than while-loops in Python. That being said, performance is not a first order determinant in Python.

Upvotes: 0

Hadi
Hadi

Reputation: 1

Try this

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

Upvotes: 0

Padraic Cunningham
Padraic Cunningham

Reputation: 180391

You could make rows an iterator and only advance when there is no error.

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

On a side note, if you are not already I would catch specific error/errors in the except, you don't want to catch everything.

If you have Falsey values you could use object as the default value:

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

Upvotes: 7

Sanke
Sanke

Reputation: 746

Have your for loop inside an infinite while loop. Check the condition where you want to restart the for loop with a if else condition and break the inner loop. have a if condition inside the while loop which is out side the for loop to break the while loop. Like this:

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

Upvotes: 1

rafaelc
rafaelc

Reputation: 59274

Although I wouldn't recommend that, the only way to do this is to make a While (True) Loop until it gets something Done.

Bear in mind the possibility of a infinite loop.

for row in rows:
    try:
        something
    except:
        flag = False
        while not flag:
            try: 
               something
               flag = True
            except:
               pass

Upvotes: 4

user2555451
user2555451

Reputation:

You could put your try/except block in another loop and then break when it succeeds:

for row in rows:
    while True:
        try:
            something
            break
        except Exception: # Try to catch something more specific
            pass

Upvotes: 27

Related Questions