Exception during list comprehension. Are intermediate results kept anywhere?
Exception during list comprehension. Are intermediate results kept anywhere?
--
Become part of the top 3% of the developers by applying to Toptal
https://topt.al/25cXVn
--
Music by Eric Matyas
https://www.soundimage.org
Track title: Peaceful Mind
--
Chapters
00:00 Question
00:52 Accepted answer (Score 26)
02:05 Answer 2 (Score 11)
03:03 Thank you
--
Full question
https://stackoverflow.com/questions/3823...
--
Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...
--
Tags
#python #listcomprehension
#avk47
ACCEPTED ANSWER
Score 26
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.
ANSWER 2
Score 11
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.