list IndexError

Steven Bethard steven.bethard at gmail.com
Wed Dec 22 16:42:16 EST 2004


Ishwor wrote:
> i am trying to remove an item 'e' from the list l

I thought it might be helpful to code some of the alternatives you've 
been given and look at the timings to put things into perspective.  The 
code:

-------------------- remove.py --------------------
def remove_lc(x, lst):
     lst[:] = [item for item in lst if item != x]

def remove_list(x, lst):
     result = []
     for item in lst:
         if item != x:
             result.append(item)
     lst[:] = result

def remove_filter(x, lst):
     lst[:] = filter(lambda item: item != x, lst)

def remove_xrange(x, lst):
     for i in xrange(len(lst)-1, -1, -1):
         if lst[i] == x:
             del lst[i]

def remove_remove(x, lst):
     while x in lst:
         lst.remove(x)

def remove_try(x, lst):
     try:
         while True:
             lst.remove(x)
     except ValueError:
         pass

def remove_ishwor(x, lst):
     for item in lst[:]:
         if item == x:
             lst.remove(x);
--------------------------------------------------

First, some timings when only 1 out of every 1000 elements needs to be 
removed.  Timings were taken with Python 2.4 on a 2.26 Ghz Windows box 
using:
     $ python -m timeit -s "import remove; lst = [x % 1000 for x in 
xrange(10000)]" "remove.remove_<name>(500, lst)"

remove_remove:  516 usec per loop
remove_try:     604 usec per loop
remove_ishwor: 1.61 msec per loop
remove_xrange: 2.29 msec per loop
remove_lc:     2.37 msec per loop
remove_list:   5.3  msec per loop
remove_filter: 5.65 msec per loop

Now, some timings when 1 out of every 10 elements needs to be removed. 
Timings were taken using:
     $ python -m timeit -s "import remove; lst = [x % 10 for x in 
xrange(10000)]" "remove.remove_<name>(5, lst)"

remove_lc:      2.03 msec per loop
remove_xrange:  2.08 msec per loop
remove_list:    4.72 msec per loop
remove_filter:  5.17 msec per loop
remove_try:    30.7  msec per loop
remove_ishwor: 31.5  msec per loop
remove_remove: 60.2  msec per loop



The moral of the story here is that, if the items to be removed only 
make up a very small percentage of the list, an approach like 
remove_remove or remove_try might be okay.  On the other hand, if you 
expect the items to be removed will make up even a moderate percentage 
of the list (e.g. 10%), then remove_lc or remove_xrange is a vastly 
better alternative.

Steve



More information about the Python-list mailing list