list.without()?
Mike Fletcher
mcfletch at vrtelecom.com
Tue Nov 16 15:26:04 EST 1999
Hmm, actually, it's only cheap for certain subsets of the problem (which I
took to be the common case). In particular, it shines for small numbers of
instances in lists of fairly arbitrary size. It falls down completely when
you are removing large numbers of instances (such as all of them). I just
tested five algos, testing 1 instance in middle of list, and a list composed
of only elements to be removed, findings, module, and raw test results
below...
Conclusions:
First is the posted algo (while,try,except,break) <without> -- gives very
good performance for the few-in-many case but very poor performance for the
many in many cases for large values of many
Second is a for loop with == test and append <without2> -- gives decent
(but not spectacular) results whenever memory effects are not a big factor,
not really a contender.
Third is the lambda solution (which does surprisingly well) <without3> --
gives acceptable but not great performance all over, seems strange that
function-call-overhead is so minor a factor.
Fourth is a backwards-index-counting scheme with del <without4> -- gives
marginally better performance than third on few-in-many case, marginally
worse than third in many-in-many case.
Fifth is Preston's remove function <remove> -- gives best results for
few-in-many case, again, very poor results in many-in-many case
Summary:
Looks like the fourth algo is likely the "winner" in this set (assuming
few-in-many is the most common case, but that many-in-many is a potential
case). Third might be preferred due to the simplicity of the implementation
and similar speed. For maximum few-in-many speed, the fifth is the most
appropriate.
Module is below, along with results run on a PIII 500 under NT. Enjoy,
Mike
8<_____ without.py ____________________
def without( source, element):
temp = source[:]
while temp:
try:
temp.remove( element )
except:
break
return temp
def without2( source, element ):
temp = []
for el in source:
if el != element:
temp.append( el )
return temp
def without3( source, element ):
return filter(lambda x, element=element: x!=element, source)
def without4( source, element ):
temp = source[:]
for index in xrange( len(temp)-1, -1, -1 ):
if temp[index] == element:
del temp[index]
return temp
def remove(list, element):
while element in list:
list.remove(element)
return list
def test( function):
import time
print "Testing function:", function
print " single element at middle:"
for dl in (10, 100, 1000, 10000, 100000, 1000000):
t = time.time()
res = function( range( dl), dl/2)
delta = time.time()-t
print " %s: %s"%(dl,delta)
if delta > 10:
print "###Note: Tests skipped due to time overrun"
break
print
print " all elements being removed:"
for dl in (10, 100, 1000, 10000, 100000, 1000000):
t = time.time()
res = function( [1]*dl, 1)
delta = time.time()-t
print " %s: %s"%(dl,delta)
if delta > 10:
print "###Note: Tests skipped due to time overrun"
break
print
if __name__ == "__main__":
#test( without )
#test( without2 )
test( without3 )
test( without4 )
test( remove )
8<_____ run results ___________________
p:\>without
Testing function: <function without at 7d7f00>
single element at middle:
10: 0.0
100: 0.0
1000: 0.0
10000: 0.00999999046326
100000: 0.0699999332428
1000000: 1.11199998856
all elements being removed:
10: 0.120000004768
100: 0.0
1000: 0.0100001096725
10000: 0.770999908447
100000: 78.7929999828
###Note: Tests skipped due to time overrun
Testing function: <function without2 at 7d7f80>
single element at middle:
10: 0.0
100: 0.0
1000: 0.0100001096725
10000: 0.039999961853
100000: 0.460999965668
1000000: 19.6879999638
###Note: Tests skipped due to time overrun
all elements being removed:
10: 0.120000004768
100: 0.0
1000: 0.0
10000: 0.0100001096725
100000: 0.110999941826
1000000: 1.16100001335
Testing function: <function without3 at 7d8f40>
single element at middle:
10: 0.0
100: 0.0
1000: 0.0
10000: 0.0299999713898
100000: 0.341000080109
1000000: 3.39499998093
all elements being removed:
10: 0.129999995232
100: 0.0
1000: 0.0
10000: 0.0299999713898
100000: 0.320000052452
1000000: 3.17499995232
Testing function: <function without4 at 7d8f60>
single element at middle:
10: 0.0
100: 0.0
1000: 0.0
10000: 0.0199999809265
100000: 0.19000005722
1000000: 1.9129999876
all elements being removed:
10: 0.120000004768
100: 0.0
1000: 0.0
10000: 0.039999961853
100000: 0.401000022888
1000000: 4.00499999523
Testing function: <function remove at 7daac0>
single element at middle:
10: 0.0
100: 0.0
1000: 0.0
10000: 0.00999999046326
100000: 0.0509999990463
1000000: 0.580000042915
all elements being removed:
10: 0.130999922752
100: 0.0
1000: 0.00999999046326
10000: 0.771000027657
100000: 79.1130000353
###Note: Tests skipped due to time overrun
More information about the Python-list
mailing list