for loops and iterating through lists
What's happening here is a list is mutated during looping.
Let's consider following code snippet:
a = [0, 1, 2, 3]
for a[-1] in a:
print a
Output is:
[0, 1, 2, 0]
[0, 1, 2, 1]
[0, 1, 2, 2]
[0, 1, 2, 2]
Each iteration:
- reads value from position currently pointed by internal pointer
- immediately assigns it to last element in list
- after that last element is printed on standard output
So it goes like:
- internal pointer points to first element, it's 0, and last element is overwritten with that value; list is
[0, 1, 2, 0]
; printed value is0
- internal pointer points to second element, it's 1, and last element is overwritten with that value; list is
[0, 1, 2, 1]
; printed value is1
- (...)
- at last step, internal pointer points to last element; last element is overwritten by itself - list does not change on last iteration; printed element also does not change.
While doing for a[-1] in a
, you actually iterate through the list and temporary store the value of the current element into a[-1]
.
You can see the loop like these instructions:
a[-1] = a[0] # a = [0, 1, 2, 0]
print(a[-1]) # 0
a[-1] = a[1] # a = [0, 1, 2, 1]
print(a[-1]) # 1
a[-1] = a[2] # a = [0, 1, 2, 2]
print(a[-1]) # 2
a[-1] = a[3] # a = [0, 1, 2, 2]
print(a[-1]) # 2
So, when you are on the third element, then 2
is stored to a[-1]
(which value is 1
, but was 0
before and 3
on start).
Finally, when it comes to the last element (and the end of the iteration), the last value stored into a[-1]
is 2
which explains why it is printed twice.