list.pop([i]) and list.remove(x) w/ for loops

Tim Hochberg tim.hochberg at ieee.org
Wed Jun 28 14:36:02 EDT 2000


dwhite2 at blue.seas.upenn.edu (David White) writes:

> I was getting some unexpected behavior when using list.remove(x),
> wondering if someone can tell me what's going on.
> 
> I have a list of 2 kinds of objects, such as [a, a, b, b, a, b].  I
> wan't to delete all the a objects out of the list while preserving
> the order of the b objects.  My code looks like this:
> 
> for o in olist:
>     if (o.type == a):
>        olist.remove(o)
> 
> Now for some reason I get a left over a object that wasn't removed.
> Anyone know why?  Using python 1.5.2.

Without getting into the gory details, modifying a list while
iterating over it can have unexpected results. Assuming your lists
aren't huge, probably the best thing to do would be to make a copy of
the list:

for o in olist[:]:
    if (o.type == a):
       olist.remove(o)

There are some other ways to deal with this if you can't make a copy,
but that's rarely the case.

You can probably get an idea of what's going on in your case by
rewriting the for loop as an equivalent while loop:

i = 0
while 1: # loop forever
   try:
      o = olist[i]
   except IndexError:
      break
   i = i + 1
   # Up to here is equivalent to "for o in olist:"
   olist.remove(o)


Everytime you delete something, olist shrinks and you end up skipping
the next element in the iteration and this results in some items not
being deleted.

-tim



More information about the Python-list mailing list