Python self referencing for loops

Viewed 414
a = [0, 1, 2, 3]
for a[-1] in a:
    print(a[-1])

The output is 0 1 2 2

Why does a[-1] change with each iteration?

4 Answers

Your code is equivalent to:

a[-1] = a[0]
print(a[-1])

a[-1] = a[1]
print(a[-1])

a[-1] = a[2]
print(a[-1])

a[-1] = a[3]
print(a[-1])

Each time through the loop it assigns the value of the current list element to a[-1] and then prints it.

You are the changing a[-1] value while iterating. The iterating variable is a reference to objects in the iterable.

lst = [[1, 2], [3, 4]]

#    ---> Iterating variable
#    |
for val in lst:
    val.append(55)
print(lst)
# [[1, 2, 55], [3, 4, 55]]

Because a is a reference to objects you're iterating over.

In your case, your iterating variable is a[-1] itself. So, you keep on changing a[-1]. You can debug by adding print(...) statements here.

a = [0, 1, 2, 3]
for a[-1] in a:
    print(a)

[0, 1, 2, 0] # a[-1] == a[0]
[0, 1, 2, 1] # a[-1] == a[1]
[0, 1, 2, 2] # a[-1] == a[2]
[0, 1, 2, 2] # a[-1] == a[3]

The first a[-1] (aka a[3]) is a variable that you assign the value you extract from a. In the 2nd to last iteration it sets a[-1] = a[2] which is 2. In the last iteration you extract a[3] which now is now the value 2.

  1. first element of a is 0
  2. set a[-1] to that
  3. print(a[-1]) so 0
  4. second element of a is 1
  5. set a[-1] to that
  6. print(a[-1]) so 1
  7. third element of a is 2
  8. set a[-1] to that
  9. print(a[-1]) so 2
  10. fourth element is the last one and you just set it to 2 in 9.
  11. set a[-1] to that, i.e. to 2 again
  12. print(a[-1]) so 2
Related