[Tutor] list iteration [iteration and mutation?]
dyoo at hkn.eecs.berkeley.edu
Mon May 3 04:50:16 EDT 2004
On Mon, 3 May 2004 tpc at csua.berkeley.edu wrote:
> when iterating through lists, may I assume that for all intents and
> purposes, 'for item in itemslist' is the same as
> 'for item in itemslist[:]' ? I first encountered the latter statement
> today, and am puzzled why one would use it as opposed to the former, which
> seems simpler and more straightforward.
The second approach,
for item in itemslist[:]:
makes a copy of the list 'itemslist', and then iterates across this copy.
for item in itemslist:
iterates directly across itemslist. So the difference is the list
Offhand, I'd prefer the first approach, unless we were doing something
funny, like mutating itemslist within the loop.
Mutating the same list that we're iterating across is often a bug-prone
For example, the following code is broken:
>>> def removeEvens(numbers):
... for i in range(len(numbers)):
... if numbers[i] % 2 == 0:
... del numbers[i]
>>> upToTwenty = range(20)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 3, in removeEvens
IndexError: list index out of range
Do you see why we're getting an error here? If not, then look at it more
Without seeing the context of the code that you're looking at, my best
guess is that an issue similar to the one above is possible if the loop
iterates directly on the list. But by iterating on a copy of the list, we
try to work around the issue of things like having indicies being yanked
right under our feet as we iterate.
If that's case, it might be nicer to explicitely rewrite:
for item in itemslist[:]: ...
as two statements:
copiedList = itemslist[:]
for item in copiedList: ...
The intent, to iterate across the copy of a list, is odd enough that it
probably needs explanation, either with a comment, or with the
two-statement breakup that we have above, so that we make that intent very
clear to a human reader.
Good luck to you!
More information about the Tutor