查找和替换列表中的元素(python)

Jam*_*mes 226 python replace list

我必须搜索一个列表并将所有出现的一个元素替换为另一个元素.到目前为止,我在代码中的尝试让我无处可去,最好的方法是什么?

例如,假设我的列表具有以下整数

>>> a = [1,2,3,4,5,1,2,3,4,5,1]
Run Code Online (Sandbox Code Playgroud)

我需要用值10替换所有出现的数字1,因此我需要的输出是

>>> a = [10, 2, 3, 4, 5, 10, 2, 3, 4, 5, 10]
Run Code Online (Sandbox Code Playgroud)

因此,我的目标是用数字10替换数字1的所有实例.

out*_*tis 456

尝试使用列表推导三元运算符.

>>> 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]
Run Code Online (Sandbox Code Playgroud)

  • 如果你想改变`a`那么你应该做'a [:] = [4 if x == 1 else x for x in a](注意完整列表切片).只需执行`a =`将创建一个新的列表`a`,其中包含与原始列表不同的`id()`(identity) (18认同)
  • @Dula你可以做一个= [4如果x == 1其他x代表x中的x],这将影响a (8认同)
  • 但这不会改变'a`虽然对吗?我认为OP希望改变 (6认同)

gho*_*g74 217

>>> a= [1, 2, 3, 4, 5, 1, 2, 3, 4, 5, 1]
>>> for n, i in enumerate(a):
...   if i == 1:
...      a[n] = 10
...
>>> a
[10, 2, 3, 4, 5, 10, 2, 3, 4, 5, 10]
Run Code Online (Sandbox Code Playgroud)

  • 这是非常好的非pythonic解决方案.考虑使用列表理解. (153认同)
  • 这是一个糟糕且非常不智能的解决方案.考虑使用列表理解. (10认同)
  • 这比列表理解更好,不是吗?它进行就地更新而不是生成新列表。 (8认同)
  • @neverendingqs:不。解释器的开销在操作中占主导地位,而理解的开销则较少。理解的表现稍好一些,尤其是通过替换条件的元素比例较高时。有一些时间安排:https://ideone.com/ZrCy6z (2认同)
  • 与使用“.index(10)”等本机列表方法相比,这确实很慢。没有理由列出每个列表元素来查找需要替换的元素。请参阅我的回答中的时间安排。 (2认同)

dam*_*zam 31

列表理解效果很好,并且使用枚举循环可以节省一些内存(b/c操作基本上就是在适当的位置完成).

还有功能编程.查看地图的用法:

>>> a = [1,2,3,2,3,4,3,5,6,6,5,4,5,4,3,4,3,2,1]
>>> map(lambda x: x if x != 4 else 'sss', a)
[1, 2, 3, 2, 3, 'sss', 3, 5, 6, 6, 5, 'sss', 5, 'sss', 3, 'sss', 3, 2, 1]
Run Code Online (Sandbox Code Playgroud)

  • +1.这太糟糕了`lambda`和`map`被认为是unpythonic. (14认同)
  • 我不认为他们是unpythonic,但许多人都这样做,包括Guido van Rossum(http://www.artima.com/weblogs/viewpost.jsp?thread=98196).这是宗派之一. (6认同)
  • 我不确定lambda或map本质上是unpythonic,但我同意列表理解比使用它们中的两个更清晰,更易读. (4认同)

roi*_*ere 28

如果要替换多个值,还可以使用字典:

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]
Run Code Online (Sandbox Code Playgroud)

  • `如果在dic.keys()中的n是性能差的话.使用`if in in dic`或`dic.get(n,n)`(默认值) (4认同)
  • @ user2914540我改进了你的答案,所以如果找不到`n`就可以了.我希望你不介意.你的'try/except`解决方案并不好. (2认同)

Joh*_*ooy 10

>>> a=[1,2,3,4,5,1,2,3,4,5,1]
>>> item_to_replace = 1
>>> replacement_value = 6
>>> indices_to_replace = [i for i,x in enumerate(a) if x==item_to_replace]
>>> indices_to_replace
[0, 5, 10]
>>> for i in indices_to_replace:
...     a[i] = replacement_value
... 
>>> a
[6, 2, 3, 4, 5, 6, 2, 3, 4, 5, 6]
>>> 
Run Code Online (Sandbox Code Playgroud)


J.P*_*aul 10

所有轻易更换110a = [1,2,3,4,5,1,2,3,4,5,1]一个可以使用下面的一行拉姆达+地图相结合,与“看,妈妈,没有如果或者维权!” :

# This substitutes all '1' with '10' in list 'a' and places result in list 'c':

c = list(map(lambda b: b.replace("1","10"), a))


dar*_*ils 8

一个班轮和最快的方法来做到这一点:

[10 if x==1 else x for x in a]
Run Code Online (Sandbox Code Playgroud)


Ana*_*tal 7

下面是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)
Run Code Online (Sandbox Code Playgroud)

这种方法有效。欢迎提出意见。希望能帮助到你 :)

还可以尝试了解outisdamzam 的解决方案是如何工作的。列表压缩和 lambda 函数是有用的工具。


Eim*_*ani 7

a = [1,2,3,4,5,1,2,3,4,5,1,12]
for i in range (len(a)):
    if a[i]==2:
        a[i]=123
Run Code Online (Sandbox Code Playgroud)

您可以使用for和while循环;但是,如果您知道内置的枚举功能,则建议使用枚举。1个


kxr*_*kxr 7

list.index()与其他答案中提供的单步迭代方法相比,在长列表和罕见事件中,使用速度提高了大约 3 倍。

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
Run Code Online (Sandbox Code Playgroud)


小智 6

我知道这是一个非常古老的问题,有很多方法可以做到。我发现的更简单的方法是使用numpypackage.json 。

import numpy

arr = numpy.asarray([1, 6, 1, 9, 8])
arr[ arr == 8 ] = 0 # change all occurrences of 8 by 0
print(arr)
Run Code Online (Sandbox Code Playgroud)

  • 假设您已经在使用“numpy”,这是一个很好的解决方案;它与所有其他好的解决方案都是相同的“O(n)”,但是将所有工作推向矢量化 C 层操作意味着它将凭借消除每个项目解释器开销而显着优于其他解决方案。 (2认同)

Jay*_*Jay 6

我的用例正在用None一些默认值替换。

我已经对这里介绍的这个问题的方法进行了计时,包括@kxr - using 的方法str.count

使用 Python 3.8.1 在 ipython 中测试代码:

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)    
Run Code Online (Sandbox Code Playgroud)

我得到:

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)
Run Code Online (Sandbox Code Playgroud)

使用内部str.index实际上比任何手动比较都要快。

我不知道测试 4 中的异常是否会比使用更费力str.count,差异似乎可以忽略不计。

请注意,map()(测试 6)返回一个迭代器而不是实际列表,因此测试 7。