1

I have found this problem, while googling, but could not understand how is it happening?

a = [0, 1, 2, 3]

for a[-1] in a: 
    print(a[-1])

Result:

0 1 2 2

Now if I print a again:

 a
 [0, 1, 2, 2]

Another similar example:

let a be the original list i.e., [0,1,2,3]

Now, let's run another for loop, but like this:

for a[0] in a:
    print(a[0])

This time result is :

0 1 2 3

But again printing a:

[3,1,2,3]

So, I have two questions:

1) How the original list is getting updated in both the cases?

2) What is the explanation of the result in the first case i.e., with the negative index for loop?

niladri chakrabarty
  • 503
  • 1
  • 7
  • 15
  • Why are you doing this `for a[0] in a`? Normally you would do `for i in a` or similar. What did you expect would happen? – Tim Sep 16 '15 at 10:45
  • Actually I was trying to loop a list backward, so I did this, but quickly realized my mistake, and corrected it, but then I found out, my original list has changed, just like mentioned above, so I just re-ran the code with a print statement, to check, what is going on. Still, couldn't understand. – niladri chakrabarty Sep 16 '15 at 10:54
  • Loop backwards like this `for i in a[::-1]` – Tim Sep 16 '15 at 10:54
  • 1
    or: `for i in reversed(a):` (this will not create a copy of `a`). – hiro protagonist Sep 16 '15 at 10:56
  • @TimCastelijns Why are you doing this for a[0] in a? Brother one interviewer asked me that question i remember, and i was like why are you asking this? lol :) – Omega Sep 02 '19 at 11:07

3 Answers3

5

note: a[-1] refers to the last element of the list.

you assign to a[index] in every loop iteration over a

for a[index] in a:

a[index] will be assigned the values a[0], a[1], ..., a[-1] during the loop and end up being assigned to

a[index] = a[-1]

usually you try not to mess with the list you are iterating over:

for item in a:
    # do something with item
hiro protagonist
  • 44,693
  • 14
  • 86
  • 111
1

This is because in Python, this:

a = [0, 1, 2, 3]
for i in a:
    ... statements ...

can be understood as this:

a = [0, 1, 2, 3]
it = iter(a)
i = next(it)
... statements ...
i = next(it)
... statements ...
i = next(it)
... statements ...
i = next(it)
... statements ...

Now if you replace i by a[index], then you end up replacing a[index] by the last element you iterated over, which is the last element in your list.

aldeb
  • 6,588
  • 5
  • 25
  • 48
1

It's somewhat intuitive if you refactor as a while loop

a = [0, 1, 2, 3]

for a[-1] in a: 
    print(a[-1])

becomes

a = [0, 1, 2, 3]
while i < len(a):
  e = a[i]
  a[-1] = e    # the last element is constantly being overwritten
  print(a[-1]) # same as a[i]

So the value of a over time is the following

[0, 1, 2, 3] # original
[0, 1, 2, 0] # prints 0
 |--------^
[0, 1, 2, 1] # prints 1
    |-----^
[0, 1, 2, 2] # prints 2
       |--^
[0, 1, 2, 2] # prints 2
         |^

Similarly in the second case

for a[0] in a:
    print(a[0])

becomes

a = [0, 1, 2, 3]
while i < len(a):
  e = a[i]
  a[0] = e    # the first element is constantly being overwritten
  print(a[0]) # same as a[i]

and the value of a is

[0, 1, 2, 3] # original
[0, 1, 2, 3] # prints 0
 ^|
[1, 1, 2, 3] # prints 1
 ^--|
[2, 1, 2, 2] # prints 2
 ^-----|
[3, 1, 2, 3] # prints 3
 ^--------|
fizzybear
  • 1,197
  • 8
  • 22