我想从列表中删除一个值,如果它存在于列表中(它可能不存在)。
a = [1, 2, 3, 4]
b = a.index(6)
del a[b]
print(a)
上面给出了错误:
ValueError: list.index(x): x not in list
所以我必须这样做:
a = [1, 2, 3, 4]
try:
b = a.index(6)
del a[b]
except:
pass
print(a)
难道没有更简单的方法吗?
我想从列表中删除一个值,如果它存在于列表中(它可能不存在)。
a = [1, 2, 3, 4]
b = a.index(6)
del a[b]
print(a)
上面给出了错误:
ValueError: list.index(x): x not in list
所以我必须这样做:
a = [1, 2, 3, 4]
try:
b = a.index(6)
del a[b]
except:
pass
print(a)
难道没有更简单的方法吗?
当前回答
一些最简单的基准测试方法:
import random
from copy import copy
sample = random.sample(range(100000), 10000)
remove = random.sample(range(100000), 1000)
%%timeit
sample1 = copy(sample)
remove1 = copy(remove)
for i in reversed(sample1):
if i in remove1:
sample1.remove(i)
# 271 ms ± 16 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# remove all instances
%%timeit
sample1 = copy(sample)
remove1 = copy(remove)
filtered = list(filter(lambda x: x not in remove1, sample1))
# 280 ms ± 18.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# remove all instances
%%timeit
sample1 = copy(sample)
remove1 = copy(remove)
filtered = [ele for ele in sample1 if ele not in remove1]
# 293 ms ± 72.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# remove all instances
%%timeit
sample1 = copy(sample)
remove1 = copy(remove)
for val in remove1:
if val in sample1:
sample1.remove(val)
# 558 ms ± 40.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# only remove first occurrence
%%timeit
sample1 = copy(sample)
remove1 = copy(remove)
for val in remove1:
try:
sample1.remove(val)
except:
pass
# 609 ms ± 11.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
# only remove first occurrence
其他回答
另一种可能是使用set而不是list,如果set适用于您的应用程序。
IE中如果你的数据不是有序的,并且没有副本,那么
my_set=set([3,4,2])
my_set.discard(1)
是没有错误的。
通常,列表只是一个方便的容器,用于存放实际上是无序的项目。有些问题询问如何从列表中删除一个元素的所有出现。如果你一开始就不想被骗,一套也很方便。
my_set.add(3)
不改变上面的my_set。
这里的许多答案都涉及到创建一个新列表。这涉及到将所有数据从旧列表复制到新列表(删除的项除外)。如果你的清单很长,你可能负担不起(或者你不应该想要)。
在这些情况下,就地更改列表要快得多。如果你必须从列表中删除一个以上的元素,这可能会很棘手。假设您循环遍历列表,并删除了一个项,那么列表将更改,标准for循环将不考虑这一点。循环的结果可能不是您所期望的。
例子:
a = [0, 1, 2, 3, 4, 5]
for i in a:
a.remove(i) # Remove all items
print(a)
Out: [1, 3, 5]
一个简单的解决方案是以相反的顺序遍历列表。在这种情况下,你会得到:
a = [0, 1, 2, 3, 4, 5]
for i in reversed(a):
a.remove(i) # Remove all items
print(a)
Out: []
然后,如果你只需要删除一些特定值的元素,你可以简单地在循环中放入一个if语句,结果是:
a = [0, 1, 2, 3, 4, 5]
for i in reversed(a):
if i == 2 or i == 3: # Remove all items having value 2 or 3.
a.remove(i)
print(a)
Out: [0, 1, 4, 5]
使用一个for循环和一个条件:
def cleaner(seq, value):
temp = []
for number in seq:
if number != value:
temp.append(number)
return temp
如果你想删除一些,但不是全部:
def cleaner(seq, value, occ):
temp = []
for number in seq:
if number == value and occ:
occ -= 1
continue
else:
temp.append(number)
return temp
通过索引除希望删除的元素之外的所有内容来覆盖列表
>>> s = [5,4,3,2,1]
>>> s[0:2] + s[3:]
[5, 4, 2, 1]
更普遍的是,
>>> s = [5,4,3,2,1]
>>> i = s.index(3)
>>> s[:i] + s[i+1:]
[5, 4, 2, 1]
正如许多其他答案所述,list.remove()将工作,但如果项不在列表中则抛出ValueError。在python 3.4+中,有一个有趣的方法来处理这个问题,使用suppress contextmanager:
from contextlib import suppress
with suppress(ValueError):
a.remove('b')