???? i can`t understand it
Alex Martelli
aleax at aleax.it
Fri Aug 8 08:49:41 EDT 2003
Sean 'Shaleh' Perry wrote:
...
> I read this as "do not remove items from a list you are iterating over".
> Pretty sure the docs comment on this as well.
Right! More generally, don't ALTER a list you are iterating over --
additions are just as deleterious as removals (indeed, potentially
worse, as an endless loop may result). If you want to alter a list,
you may iterate over a COPY of that list, e.g.:
for item in list(mylist):
if iswonderful(item):
mylist.append(item) # better have 2 copies of this item
but in some cases even that solution is inferior. For example,
consider the task "remove all multiples of 3 from my list".
# Naive implementation of this idea:
def remove3s(mylist):
for item in list(mylist):
if item%3 == 0: mylist.remove(item)
# let's see how long it takes...
import timeit
timeit.remove3s = remove3s
t = timeit.Timer('x=666*[33]+666*[22]; remove3s(x)')
print 'remove3s:', min(t.repeat(3,100))
# perhaps a better idea...:
def cleano3s(mylist):
clean = [item for item in mylist if item%3]
mylist[:] = clean
# and how about its timing, then?
timeit.cleano3s = cleano3s
t = timeit.Timer('x=666*[33]+666*[22]; cleano3s(x)')
print 'cleano3s:', min(t.repeat(3,100))
On my machine, this gives:
remove3s: 0.759788990021
cleano3s: 0.178290963173
i.e., the 'clean' idea (build a new "cleaned-up" list with a list
comprehension then substitute it in-place in the original list)
is over 4 times faster than the 'remove' idea for this case... the
'remove' method of a list in general is O(N) [whenre N is the
length of the list), so a loop of O(N) removes is going to be
O(N squared), while a list comprehension is O(N). For large enough
lists, these differences do matter.
Alex
More information about the Python-list
mailing list