Reputation: 319
from pprint import *
sites = [['a','b','c'],['d','e','f'],[1,2,3]]
pprint(sites)
for site in sites:
sites.remove(site)
pprint(sites)
outputs:
[['a', 'b', 'c'], ['d', 'e', 'f'], [1, 2, 3]]
[['d', 'e', 'f']]
why is it not None, or an empty list [] ?
Upvotes: 20
Views: 26725
Reputation: 91017
Normally I would expect the iterator to bail out because of modifying the connected list. With a dictionary, this would happen at least.
Why is the d, e, f stuff not removed? I can only guess: Probably the iterator has an internal counter (or is even only based on the "fallback iteration protocol" with getitem).
I. e., the first item yielded is sites[0]
, i. e. ['a', 'b', 'c']
. This is then removed from the list.
The second one is sites[1]
- which is [1, 2, 3]
because the indexes have changed. This is removed as well.
And the third would be sites[2]
- but as this would be an index error, the iterator stops.
Upvotes: 3
Reputation:
Because resizing a collection while iterating over it is the Python equivalent to undefined behaviour in C and C++. You may get an exception or subtly wrong behaviour. Just don't do it. In this particular case, what likely happens under the hood is:
remove
operation, the item at index 1 is the item that started out at index 2 (the last item).Upvotes: 12
Reputation:
It's because you're modifying a list as you're iterating over it. You should never do that.
For something like this, you should make a copy of the list and iterate over that.
for site in sites[:]:
sites.remove(site)
Upvotes: 55