1

Here is a simple question. My task is to loop a list and print each element it has. After each printing, I intend to delete this element from the list as well. My code is:

>> a = [1,2]
>> for x in a:
>>   print x
>>   a.remove(x)
>>   print a

The output is:

>> 1
>> [2]

However, something strange happens here: Only 1 has been printed and it seems after removing 1 from the list, the program jumps out of loop directly. My assumption is after changing the content of the list, the iterator may also be affected, but I'm not very sure. A more safe way is:

>> a = [1,2]
>> b = list(a)
>> for x in b:
>>   print x
>>   a.remove(x)
>>   print a

Could someone please provide me any more advanced explanation?

Dickens LI
  • 11
  • 2
  • 1
    The iterator tracks the position, yes. But why would you bother removing each element? You'll end up with an empty list. – jonatan Oct 20 '17 at 21:22
  • 3
    `b = list(a)` creates a copy of the list, so `a` and `b` become different objects. [This](https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/) might be useful. – roganjosh Oct 20 '17 at 21:23
  • [This answer](https://stackoverflow.com/a/34238688/8747) has a decent explanation. – Robᵩ Oct 20 '17 at 21:25
  • If you want to iterate over a list while modyfying it, use a `while` loop or make a copy of the list for a `for` loop. – dawg Oct 20 '17 at 21:28
  • visualize your code - http://www.codeskulptor.org/viz/ – marmeladze Oct 20 '17 at 21:29
  • just by curious haha and want to figure out how python for-loop works. Is it like Java's `for(Element e: list)` and C#'s `foreach`? Each time the iterator call `has_next()` and if negative, the loop will terminate. – Dickens LI Oct 20 '17 at 21:30
  • The for-statement will ask the iterable for an iterator `iter(a)` and keep asking that iterator for next value `next(iterator)` until there's an exception marking the end which the for-statement catches and stops looping – jonatan Oct 20 '17 at 21:33

2 Answers2

2
a = [1,2]
while a:
    print a.pop(0)
    print a
Ghilas BELHADJ
  • 13,412
  • 10
  • 59
  • 99
0

You should not remove elements from a list that you are iterating over with for.

Your guess is close -- you can see more clearly what's happening if you use a longer list:

a = [1,2,3,4,5]
for x in a:
    print x
    a.remove(x)
    print a

output:

1
[2, 3, 4, 5]
3
[2, 4, 5]
5
[2, 4]

It prints the element at index 0, then index 1, then index 2... and by then there is no index 3.

In your example it prints the element at index 1, then there is no index 2.

Nathan Hinchey
  • 1,191
  • 9
  • 30