I found this code snippet to be very interesting.
a = [0, 1, 2, 3]
for a[-1] in a:
print(a)
Output is as follows:
[0,
What happens is
0 SETUP_LOOP 24 (to 26)
2 LOAD_GLOBAL 0 (a)
4 GET_ITER
>> 6 FOR_ITER 16 (to 24)
8 LOAD_GLOBAL 0 (a) //ARRAY (TOS1)
10 LOAD_CONST 2 (-1) //DEST (TOS)
12 STORE_SUBSCR //ARRAY[DEST] = TOS2*
14 LOAD_GLOBAL 1 (print)
16 LOAD_GLOBAL 0 (a)
18 CALL_FUNCTION 1
20 POP_TOP
22 JUMP_ABSOLUTE 6
>> 24 POP_BLOCK
>> 26 LOAD_CONST 0 (None)
28 RETURN_VALUE
*So if someone could clarify that TOS2 is actually the 'visited' value of the ARRAY?
It works as expected. (For some interpretation of "expected", at least.)
Re-writing your code to this, to prevent any misinterpretation of what a[-1]
is at any point:
a = [a for a in range(0,4)]
for b in a:
print (b)
a[-1] = b
print (a)
shows us
0
[0, 1, 2, 0]
1
[0, 1, 2, 1]
2
[0, 1, 2, 2]
2
[0, 1, 2, 2]
which makes it clear that the b
assignment to a[-1]
is done immediately, changing the list while iterating.
The four loops do the following:
a[-1]
gets set to the first value of the list, 0
. The result is now [0,1,2,0]
.a[-1]
gets set to the second value, 1
. The result is (quite obviously) [0,1,2,1]
.a[-1]
gets set to 2
and so the result is [0,1,2,2]
– again, only a[-1]
gets changed.a[-1]
gets set to the last value in a
, so effectively it does not change and the final result is [0,1,2,2]
.a[-1] prints the same value in a[3], the last index in the list. Edit: see comment below for the explanation for this.
The result reads as follows:
[0, 1, 2, 0] -> same as [0, 1, 2, 3], but with a[i] (in this case, a[-1] == a[3]) is replaced with the value at a[0]
[0, 1, 2, 1] -> [0, 1, 2, 3] but a[i] is replaced with the value at a[1]
[0, 1, 2, 2] -> [0, 1, 2, 3] but a[i] is replaced with the value at a[2]
[0, 1, 2, 2] -> [0, 1, 2, 3] but a[i] is replaced with the value at a[3] from the previous iteration.