For-each behavior while modifying a collection
Wolfgang Maier
wolfgang.maier at biologie.uni-freiburg.de
Thu Nov 28 12:21:57 EST 2013
Valentin Zahnd <v.zahnd <at> gmail.com> writes:
>
> Hello
>
> For-each does not iterate ober all entries of collection, if one
> removes elements during the iteration.
>
> Example code:
>
> def keepByValue(self, key=None, value=[]):
> for row in self.flows:
> if not row[key] in value:
> self.flows.remove(row)
>
> It is clear why it behaves on that way. Every time one removes an
> element, the length of the colleciton decreases by one while the
> counter of the for each statement is not.
> The questions are:
> 1. Why does the interprete not uses a copy of the collection to
> iterate over it? Are there performance reasons?
> 2. Why is the counter for the iteration not modified?
>
> Valentin
>
I guess because it's difficult to generalize this idea.
Python for loops use the iterator protocol, i.e., in order to be usable in a
for loop all an object has to provide is an __iter__ and a __next__ method,
but your suggestion #1 would require it to define a copy method in addition.
As for #2: there is no such thing as a loop counter in a standard for loop,
but it's the iterated object that decides on the next value the loop will
see, and there's no way to move back, e.g.:
class jumplist (list):
def __iter__(self):
n=0
while True:
if n%3:
yield self[n]
else:
yield None
n+=1
if n>=len(self):
break
jumper=jumplist(range(10))
for element in jumper:
print(element)
---->
None
1
2
None
4
5
None
7
8
None
Best,
Wolfgang
More information about the Python-list
mailing list