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,
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].