例如,假设我的列表具有以下整数
>>> a = [1,2,3,4,5,1,2,3,4,5,1]
,我需要将所有出现的1替换为值10,所以我需要的输出是
数字1与数字10的实例。
#1 楼
>>> 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]
评论
这是一个糟糕且非常不符合Python的解决方案。考虑使用列表理解。
– AdHominem
16年12月31日在11:56
如果不是Python的话,这很好。考虑使用列表理解。
–让·弗朗索瓦·科贝特(Jean-FrançoisCorbett)
17-2-2在13:35
这比列表理解要好,不是吗?它执行就地更新,而不是生成新列表。
–neverendingqs
19年5月13日在18:59
@neverendingqs:否。在翻译操作中占主导地位,而理解力则更少。理解性能稍好,尤其是在通过替换条件的元素比例更高的情况下。有一些时间安排:ideone.com/ZrCy6z
– user2357112支持Monica
3月31日23:26
与使用本机列表方法(如.index(10))相比,这确实很慢。没有理由列出每个列表元素来查找需要替换的元素。请在此处查看我的答案中的时间安排。
–道格
5月10日19:09
#2 楼
尝试使用列表推导和三元运算符。>>> 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]
评论
但这并不能改变对吗?我认为OP希望改变
–杜拉
16-2-3在23:26
@Dula您可以执行a = [4,如果x == 1,则x表示a中的x],这将影响
– Alekhya Vemavarapu
16年4月11日在7:57
@Dula:关于a是否应该突变的问题尚不清楚,但是(如Alekhya所示)在使用列表推导时处理这两种情况都是微不足道的。
– outis
16年8月15日在11:55
如果要变异a,则应执行a [:] = [4,如果x == 1,则x替代a中的x](请注意完整列表片)。只需执行a =就会创建一个新列表a,该列表的id()(identity)与原始列表不同
– Chris_Rands
17年4月25日在12:15
#3 楼
如果要替换多个值,则还可以使用字典: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]
评论
如果在dic中找不到n,这不会引发错误吗?
–尼尔A.
16年8月17日在23:17
@ user2914540我改善了您的答案,因此,如果找不到n,它可以工作。我希望你不要介意。您的try / except解决方案不好。
– jrjc
16年8月18日在8:48
哦,是的,那更好。
–roipoussiere
16年8月18日在8:55
@jrjc @roipoussiere用于就地替换,try-except至少快50%!看看这个答案
–生活平衡
16年11月23日在3:25
如果dic.keys()中的n在性能方面不好。在dic或dic.get(n,n)中使用n(默认值)
–Jean-FrançoisFabre♦
16 Dec 27 '22:48
#4 楼
列表理解效果很好,通过枚举进行循环可以节省一些内存(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]
评论
+1。太糟糕了,lambda和map被认为是非Python的。
– outis
2010-4-7在0:02
我不确定lambda或map本质上是非Python语言的,但是我同意列表理解比将两者结合使用更干净,更易读。
– damzam
2010-4-7在2:14
我本人并不认为它们具有不可思议的特性,但包括Guido van Rossum(artima.com/weblogs/viewpost.jsp?thread=98196)在内,很多人都不会这样做。这是那些宗派主义的事情之一。
– outis
2010年4月8日在1:29
#5 楼
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
您可以使用for和while循环;但是,如果您知道内置的枚举函数,则建议使用Enumerate.1
评论
当您需要对列表项执行更复杂的操作时,这是唯一明智的(可读的)方法。例如,如果每个列表项都是一个长字符串,则需要某种搜索和替换。
–not2qubit
18年11月19日在6:50
#6 楼
>>> 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]
>>>
评论
中速但非常明智的方法。请查看我的答案中的时间安排。
–道格
5月10日19:06
#7 楼
为了轻松地用1
中的10
替换所有a = [1,2,3,4,5,1,2,3,4,5,1]
,可以使用以下单行lambda + map组合,以及“看,妈,没有IF或FOR!” :# 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))
评论
迄今为止最慢的方法。您在每个列表元素上调用一个lambda。
–道格
5月10日19:06
#8 楼
这是一个很酷且可扩展的设计模式,可在O(n)
时间运行... a = [1,2,3,4,5,6,7,6,5,4,3,2,1]
replacements = {
1: 10,
2: 20,
3: 30,
}
a = [replacements.get(x, x) for x in a]
print(a)
# Returns [10, 20, 30, 4, 5, 6, 7, 6, 5, 4, 30, 20, 10]
评论
这是一个最佳解决方案。它具有可读性,可理解性,高性能,并且还足够健壮,可以在将来包括新的替代品,因为它正在将这种多重替代策略与替代对象一起使用。
–维克多
9月13日18:06
#9 楼
以下是Python 3.x中非常简单的方法。此方法有效。欢迎发表评论。希望对您有所帮助:)
也请尝试了解outis和damzam解决方案的工作方式。列表压缩和lambda函数是有用的工具。
#10 楼
我的用例是用一些默认值替换None
。 我已经定时解决了这里提出的问题,包括@kxr提出的方法-使用
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)
我得到:
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)
使用内部
str.index
实际上比任何手动比较都快。我不知道测试4中的异常是否比使用
str.count
更费力,差异似乎可以忽略不计。不是实际的列表,因此请测试7。#11 楼
在长列表和罕见情况下,使用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
评论
这是我找到的最快的方法。请查看我的答案中的时间安排。大!
–道格
5月10日19:05
#12 楼
我知道这是一个非常老的问题,并且有无数种方法可以解决。我发现的最简单的方法是使用numpy
软件包。 import numpy
arr = numpy.asarray([1, 6, 1, 9, 8])
arr[ arr == 8 ] = 0 # change all occurrences of 8 by 0
print(arr)
#13 楼
您可以在python中简单地使用列表推导:def replace_element(YOUR_LIST, set_to=NEW_VALUE):
return [i
if SOME_CONDITION
else NEW_VALUE
for i in YOUR_LIST]
对于您的情况,要将所有出现的1替换为10,代码片段将如下所示:
def replace_element(YOUR_LIST, set_to=10):
return [i
if i != 1 # keeps all elements not equal to one
else set_to # replaces 1 with 10
for i in YOUR_LIST]
评论
尽管此代码段可以解决问题,但提供说明确实有助于提高您的帖子质量。请记住,您将来会为读者回答这个问题,而这些人可能不知道您提出代码建议的原因。也请尽量不要在代码中加入解释性注释,这会降低代码和解释的可读性!
–菲诺
18年5月23日在10:10
#14 楼
for i in range(0, len(lst)):
lst.insert(i, lst[i])
lst.remove(lst[i+1])
#15 楼
使用枚举函数可以很容易地做到这一点。code-
lst=[1,2,3,4,1,6,7,9,10,1,2]
for index,item in enumerate(lst):
if item==1:
lst[index]=10 #Replaces the item '1' in list with '10'
print(lst)
#16 楼
仅查找和替换一项your_list = [1,2,1] # replace the first 1 with 11
loc = your_list.index(1)
your_list.remove(1)
your_list.insert(loc, 11)
评论
顺便问一下,这是做什么用的?stackoverflow.com/q/1540049/819417的副本