Home > OS >  Python for-loop undo all processes in case of raised Exception
Python for-loop undo all processes in case of raised Exception

Time:03-28

Small example:

x = ['idjs', 'w', '2331']
fin = []
for row in x:
    try:
        fin.append(row)
        fin.append(row[1])
    except:
        continue

print(fin)

Output: ['idjs', 'd', 'w', '2331', '3']

In the case above, exception was raised when row='w' and fin.append(row[1])
Is it possible that in cases where exception is raised for a component in a for loop, the previous mulitple processes also undo their operation?
There could be multiple processes in the loop, this is just an example. Is there a way to handle all without specifically mentioning them and removing the component?
Expected output: ['idjs', 'd', '2331', '3']

CodePudding user response:

Perhaps use list.extend instead of appending twice:

x = ['idjs', 'w', '2331']
fin = []
for row in x:
    try:
        fin.extend([row, row[1]])
    except:
        continue

Output:

['idjs', 'd', '2331', '3']

CodePudding user response:

In the simple example you have given, enke's suggestion of using extend is easiest

In more complex code, it almost sounds like you want an ExitStack; this will let you register clean-up which is invoked as you exit the context, which may be built-in (eg. closing files, releasing locks) or custom (call a function, with or without information about exceptions)

A slightly simplified example from the manual:

files = []
with ExitStack() as stack:
    for fname in filenames:
        files.append(stack.enter_context(open(fname)))

This will open all the files, but if any of them fails to open (not found), all the already-opened files will be automatically closed.

You can also register functions to be called as part of the clean-up:

    stack.callback(lambda: print("Exiting the stack"))

Another option (or in combination), depending on what you're doing in those 20 steps, you can take those steps and put them into their own function or class and make that a context manager. That would let you make sure that the set-up and clean-up always happens in a matched-up way, without cluttering up your main code.

CodePudding user response:

x = ['.', 'w', '2331']
fin = []
for row in x:
    B=fin.copy()
    try:
        fin.append(row)
        fin.append(row[1])
    except:
        fin=B.copy()

The solution is to create a copy of list in every iteration, if exceptions are raised then we can copy the previously copied list to the orignal list.

  • Related