finding and replacing elements in a list

前端 未结 16 2457
南方客
南方客 2020-11-22 05:41

I have to search through a list and replace all occurrences of one element with another. So far my attempts in code are getting me nowhere, what is the best way to do this?<

相关标签:
16条回答
  • 2020-11-22 05:54

    Try using a list comprehension and the ternary operator.

    >>> a=[1,2,3,1,3,2,1,1]
    >>> [4 if x==1 else x for x in a]
    [4, 2, 3, 4, 3, 2, 4, 4]
    
    0 讨论(0)
  • 2020-11-22 05:54
    for i in range(0, len(lst)):
        lst.insert(i, lst[i])
        lst.remove(lst[i+1])
    
    0 讨论(0)
  • 2020-11-22 05:57

    If you have several values to replace, you can also use a dictionary:

    a = [1, 2, 3, 4, 1, 5, 3, 2, 6, 1, 1]
    dic = {1:10, 2:20, 3:'foo'}
    
    print([dic.get(n, n) for n in a])
    
    > [10, 20, 'foo', 4, 10, 5, 'foo', 20, 6, 10, 10]
    
    0 讨论(0)
  • 2020-11-22 05:57

    The following is a very straightforward method in Python 3.x

     a = [1,2,3,4,5,1,2,3,4,5,1]        #Replacing every 1 with 10
     for i in range(len(a)):
       if a[i] == 1:
         a[i] = 10  
     print(a)
    

    This method works. Comments are welcome. Hope it helps :)

    Also try understanding how outis's and damzam's solutions work. List compressions and lambda function are useful tools.

    0 讨论(0)
  • 2020-11-22 06:02

    On long lists and rare occurrences its about 3x faster using list.index() - compared to single step iteration methods presented in the other answers.

    def list_replace(lst, old=1, new=10):
        """replace list elements (inplace)"""
        i = -1
        try:
            while 1:
                i = lst.index(old, i + 1)
                lst[i] = new
        except ValueError:
            pass
    
    0 讨论(0)
  • 2020-11-22 06:07

    My usecase was replacing None with some default value.

    I've timed approaches to this problem that were presented here, including the one by @kxr - using str.count.

    Test code in ipython with Python 3.8.1:

    def rep1(lst, replacer = 0):
        ''' List comprehension, new list '''
    
        return [item if item is not None else replacer for item in lst]
    
    
    def rep2(lst, replacer = 0):
        ''' List comprehension, in-place '''    
        lst[:] =  [item if item is not None else replacer for item in lst]
    
        return lst
    
    
    def rep3(lst, replacer = 0):
        ''' enumerate() with comparison - in-place '''
        for idx, item in enumerate(lst):
            if item is None:
                lst[idx] = replacer
    
        return lst
    
    
    def rep4(lst, replacer = 0):
        ''' Using str.index + Exception, in-place '''
    
        idx = -1
        # none_amount = lst.count(None)
        while True:
            try:
                idx = lst.index(None, idx+1)
            except ValueError:
                break
            else:
                lst[idx] = replacer
    
        return lst
    
    
    def rep5(lst, replacer = 0):
        ''' Using str.index + str.count, in-place '''
    
        idx = -1
        for _ in range(lst.count(None)):
            idx = lst.index(None, idx+1)
            lst[idx] = replacer
    
        return lst
    
    
    def rep6(lst, replacer = 0):
        ''' Using map, return map iterator '''
    
        return map(lambda item: item if item is not None else replacer, lst)
    
    
    def rep7(lst, replacer = 0):
        ''' Using map, return new list '''
    
        return list(map(lambda item: item if item is not None else replacer, lst))
    
    
    lst = [5]*10**6
    # lst = [None]*10**6
    
    %timeit rep1(lst)    
    %timeit rep2(lst)    
    %timeit rep3(lst)    
    %timeit rep4(lst)    
    %timeit rep5(lst)    
    %timeit rep6(lst)    
    %timeit rep7(lst)    
    

    I get:

    26.3 ms ± 163 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
    29.3 ms ± 206 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
    33.8 ms ± 191 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
    11.9 ms ± 37.8 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    11.9 ms ± 60.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    260 ns ± 1.84 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
    56.5 ms ± 204 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
    

    Using the internal str.index is in fact faster than any manual comparison.

    I didn't know if the exception in test 4 would be more laborious than using str.count, the difference seems negligible.

    Note that map() (test 6) returns an iterator and not an actual list, thus test 7.

    0 讨论(0)
提交回复
热议问题