When using try-except in a for loop context, the commands executed so far are obviously done with
a = [1, 2, 3, 'text', 5]
b = []
try:
for k in range(len(a)):
b.append(a[k] + 4)
except:
print('Error!')
print(b)
results with
Error!
[5, 6, 7]
However the same is not true for list comprehensions
c=[]
try:
c = [a[k] + 4 for k in range(len(a))]
except:
print('Error!')
print(c)
And the result is
Error!
[]
Is the intermediate list, built before the exception occurred, kept anywhere? Is it accessible?
The list comprehension intermediate results are kept on an internal CPython stack, and are not accessible from the Python expressions that are part of the list comprehension.
Note that Python executes the [.....]
first, which produces a list object, and only then assigns that result to the name c
. If an exception occurs within the [....]
expression, the expression is terminated and exception handling kicks in instead. Your print(c)
expression thus can only ever show the previous object that c
was bound to, which here is an empty list object. It could have been anything else:
>>> c = 'Anything else'
>>> try:
... c = [2 // i for i in (1, 0)]
... except ZeroDivisionError:
... pass
...
>>> c
'Anything else'
In your first example, no new list object is produced. You instead manipulate (using b.append()
) an existing list object, which is why you can see what all successful b.append()
calls have done to it.
Let's look at the bytecode:
>>> def example():
... c=[]
... try:
... c = [a[k] + 4 for k in range(len(a))]
... except:
... print('Error!')
... print(c)
...
>>> import dis
>>> dis.dis(example)
--- removed some instructions
27 GET_ITER
>> 28 FOR_ITER 20 (to 51)
31 STORE_FAST 1 (k)
34 LOAD_GLOBAL 2 (a)
37 LOAD_FAST 1 (k)
40 BINARY_SUBSCR
41 LOAD_CONST 1 (4)
44 BINARY_ADD
45 LIST_APPEND 2
48 JUMP_ABSOLUTE 28
>> 51 STORE_FAST 0 (c)
--- more instructions...
As you can see, the list comprehension is translated to a series of instructions GET_ITER
...JUMP_ABSOLUTE
. The next instruction STORE_FAST
is the one that modifies c
. If any exception occurs before it, c
will not have been modified.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With