is there a better way...

Cliff Wells logiplexsoftware at earthlink.net
Fri May 10 16:42:33 EDT 2002


On Fri, 10 May 2002 17:32:37 +0200
holger krekel wrote:

> Christopher Encapera wrote:
> > to loop over a list and replace an element based on its value than:
> > 
> > x = [1,2,3,4,5,6,7,8,9]
> > y = len(x)
> > z = 0
> > while z < y:
> >     element = x[z]
> >     if element == 5: x[z] = '678'
> >     z = z +1
> >  
> > 
> > Another words is there a way to do this with a "for" statement - some
method
> > that will return the current z (of x[z]) in the loop?
> 
> def subst(elem):
>     if elem==5:
>         elem='678'
>     return elem
> 
> m= map(subst, [1,2,3,4,5,6,7,8,9])
> >>> print m
> [1, 2, 3, 4, '678', 6, 7, 8, 9]

This is fast, but not general since the new value is hardcoded in subst(). 
Some variations:

def replaceItem(l, old, new):
    def subst(i):
        if i == old:
            return new
        return i
    return map(subst, l)

Or using list comprehension (shorter, but not quite as fast):

def replaceItem(l, old, new):
    return [[i, new][i == old] for i in l]

Times are 0.09s and 0.13s respectively for replacing every 4th item in a 40,000
item list of ints.

However, neither of these is as fast as the most obvious solution (posted by
Mark McEahern earlier):

def replaceItem(l, old, new):
    x = list(l)
    for i in range(len(x)):
        if x[i] == old:
            x[i] = new
    return x

Which has a time of 0.06s on the same list.  It is also better in that it can
be easily changed to modify the list in place:

def replaceItem(l, old, new):
    for i in range(len(l)):
        if l[i] == old:
            l[i] = new

Which I didn't time, but would clearly be a bit faster still (and more
memory-efficient).

As an aside, the solution I posted earlier using list.index() had horrible
times as the number of items to be replaced increased :(  I suppose it should
have been obvious (or maybe it was - just not to me at that moment ;)

Regards,

-- 
Cliff Wells, Software Engineer
Logiplex Corporation (www.logiplex.net)
(503) 978-6726 x308  (800) 735-0555 x308





More information about the Python-list mailing list