有没有一种简单的方法可以按值删除列表元素?


942
a = [1, 2, 3, 4]
b = a.index(6)

del a[b]
print(a)

上面显示了以下错误:

Traceback (most recent call last):
  File "D:\zjm_code\a.py", line 6, in <module>
    b = a.index(6)
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)

但是,没有简单的方法可以做到这一点吗?


14
您计算列表中的索引6。但是6不在您的清单中……那应该怎么办?:)
约翰尼斯·查拉

5
这与删除列表中的值无关,因为您的代码未到达del语句。也许你应该重命为“我如何才能不在列表中的值的索引显而易见的答案-你不能。
戴夫·柯比

57
@戴夫好吧,不是真的。他想从列表中删除一个项目,而不管它是否存在,而不是获取不存在的项目的索引。这个问题问得很好。
2011年

除了要点之外,光是except不好的做法except Exception最少使用。
wjandrea

Answers:


1562

要删除列表中元素的首次出现,只需使用list.remove

>>> a = ['a', 'b', 'c', 'd']
>>> a.remove('b')
>>> print(a)
['a', 'c', 'd']

请注意,它不会删除所有出现的元素。为此使用列表理解。

>>> a = [10, 20, 30, 40, 20, 30, 40, 20, 70, 20]
>>> a = [x for x in a if x != 20]
>>> print(a)
[10, 30, 40, 30, 40, 70]

144
如果元素不在列表中,则失败。:)
ibz

21
即使元素不在列表中,@ ibz列表理解也不会失败,不是吗?
IsaacS 2013年

76
为了澄清任何略读,它会引发ValueError异常,因此“失败”。
Casey Falk 2014年

10
列表理解会更改列表引用,因此,如果某处存在该引用的副本,则不会再进行删除。
塞巴斯蒂安2015年

removeO(n)的复杂度是多少?
Rasmi Ranjan Nayak

184

通常,如果您告诉Python做一些它无法做的事情,它将抛出一个Exception,因此您必须执行以下任一操作:

if c in a:
    a.remove(c)

要么:

try:
    a.remove(c)
except ValueError:
    pass

只要它是您期望的并且可以正确处理的异常,它就不一定是一件坏事。


9
预防胜于治疗。如果可以先检查异常情况(示例a),则应该这样做。
Gusdor

82
虽然在其他语言中也是如此,但是在Python中,“请求宽恕比允许许可更容易”。docs.python.org/2/glossary.html#term-eafp
Dave Webb

6
@Gusdor:如果列表在线程之间共享,则a.remove(c)尽管进行了if c in a检查,但仍然可能失败(a可以在c in a检查之后但在a.remove(c)调用之前在另一个线程中进行修改)。try/except或可以使用锁来避免比赛情况。
jfs

7
@JFSebastian如果在线程之间共享列表,并且您没有应用关键部分,那么您将遇到更大的问题。
Gusdor

4
@ Gusdor,Pythonique习惯用法是不检查就尝试并捕获异常(如果发生)。它效率更高(仅一次查找而不是两次查找),尽管比较难看
Jeet

80

你可以做

a=[1,2,3,4]
if 6 in a:
    a.remove(6)

但以上需要在列表中搜索6 2次,因此尝试使用除外会更快

try:
    a.remove(6)
except:
    pass

55

考虑:

a = [1,2,2,3,4,5]

要排除所有情况,可以在python中使用filter函数。例如,它看起来像:

a = list(filter(lambda x: x!= 2, a))

因此,它将保留的所有元素a != 2

仅取出其中一项使用

a.remove(2)

你为什么要包裹filter()另一个list()?根据手册,它已经返回了列表。
Olaf Dietsche 2015年

8
@OlafDietsche在Python 3.x中,它返回一个过滤器对象(在2.x中,它返回一个列表),因此我必须将“ a”强制转换为列表,以使其具有任何功能。
mathwizurd 2015年

17

这是就地执行此操作的方法(无需列表理解):

def remove_all(seq, value):
    pos = 0
    for item in seq:
        if item != value:
           seq[pos] = item
           pos += 1
    del seq[pos:]

非常聪明-我真的很喜欢-不幸的是,它似乎没有最流行的答案那么有效。对于只有少量希望删除的值的巨型列表,gil的解决方案实际上要快得多。
2014年

1
@Larold最快的方法是一个单独的问题。一般情况下,我的钱都在清单上。如果该值在输入列表中很频繁且未使用列表理解,则此解决方案应能很好地执行。在Cython中尝试Pypy,numpy数据。[@吉尔的答案是O(n*n)不必要的(比较1e6和1e12 –您不想冒险使用后者)。while 1: L.remove(value)然后ValueError使用valueCPython中的一些列表或小列表可以很好地 返回。
jfs

13

如果您知道要删除的值,这是一种简单的方法(无论如何,我仍然可以想到):

a = [0, 1, 1, 0, 1, 2, 1, 3, 1, 4]
while a.count(1) > 0:
    a.remove(1)

你会得到 [0, 0, 2, 3, 4]


4
为什么不用while 1 in a:作循环结构?
TerminalDilettante

12
这是O(n^2)理解的地方O(n)
疯狂物理学家

1
当然,@ MadPhysicist是正确的,即使我们不在乎性能,TerminalDilettante的版本也更加Python化。2013年是我刚开始学习Python的时候,如今,我常常为自己当时的写作感到ham愧。
gil

11

如果集合适用于您的应用程序,则另一种可能性是使用集合而不是列表。

IE,如果您的数据未排序,并且没有重复,则

my_set=set([3,4,2])
my_set.discard(1)

没有错误。

通常,列表只是一个方便存放实际未排序商品的容器。有一些问题询问如何从列表中删除所有出现的元素。如果您不想一开始就喜欢做傻瓜,那么再说一遍就很方便了。

my_set.add(3)

不会从上面改变my_set。


10

如许多其他答案所述,它list.remove()可以工作,但ValueError如果该项目不在列表中,则抛出a 。在python 3.4及更高版本中,有一种有趣的方法可以使用抑制上下文管理器来处理此问题:

from contextlib import suppress
with suppress(ValueError):
    a.remove('b')

8

通过使用列表的remove方法,可以更轻松地在列表中查找值,然后删除该索引(如果存在)。

>>> a = [1, 2, 3, 4]
>>> try:
...   a.remove(6)
... except ValueError:
...   pass
... 
>>> print a
[1, 2, 3, 4]
>>> try:
...   a.remove(3)
... except ValueError:
...   pass
... 
>>> print a
[1, 2, 4]

如果您经常这样做,则可以将其包装在一个函数中:

def remove_if_exists(L, value):
  try:
    L.remove(value)
  except ValueError:
    pass

8

这个例子很快,并且将从列表中删除该值的所有实例:

a = [1,2,3,1,2,3,4]
while True:
    try:
        a.remove(3)
    except:
        break
print a
>>> [1, 2, 1, 2, 4]

2
如果你这样做,你真的应该只breakexcept ValueError
Anthon '18年


7

如果您的元素是不同的,那么简单的集合差异就可以了。

c = [1,2,3,4,'x',8,6,7,'x',9,'x']
z = list(set(c) - set(['x']))
print z
[1, 2, 3, 4, 6, 7, 8, 9]

2
如果您的元素与众不同,并且您不关心顺序
Tom Zych '18

2

我们还可以使用.pop:

>>> lst = [23,34,54,45]
>>> remove_element = 23
>>> if remove_element in lst:
...     lst.pop(lst.index(remove_element))
... 
23
>>> lst
[34, 54, 45]
>>> 

2

通过索引除您要删除的元素以外的所有内容来覆盖列表

>>> s = [5,4,3,2,1]
>>> s[0:2] + s[3:]
[5, 4, 2, 1]

2

有一个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

1
 list1=[1,2,3,3,4,5,6,1,3,4,5]
 n=int(input('enter  number'))
 while n in list1:
    list1.remove(n)
 print(list1)

它不使用过滤器功能
Ravikiran D

1

举例来说,我们要从x中删除所有1。这就是我要做的:

x = [1, 2, 3, 1, 2, 3]

现在,这是我的方法的实际用法:

def Function(List, Unwanted):
    [List.remove(Unwanted) for Item in range(List.count(Unwanted))]
    return List
x = Function(x, 1)
print(x)

这是我的方法,只需一行:

[x.remove(1) for Item in range(x.count(1))]
print(x)

两者都将其作为输出:

[2, 3, 2, 3, 2, 3]

希望这可以帮助。PS,请注意,这是在3.6.2版中编写的,因此您可能需要针对旧版本进行调整。


1

也许您的解决方案适用于int,但不适用于字典。

一方面,remove()对我不起作用。但也许它适用于基本类型。我猜下面的代码也是从对象列表中删除项目的方法。

另一方面,“ del”也无法正常工作。就我而言,使用python 3.6:当我尝试使用“ del”命令从“ for”气泡中的列表中删除元素时,python会更改进程中的索引,而bucle会在时间之前过早停止。仅当您以相反的顺序删除一个元素时,它才有效。这样,您在遍历时不会更改未决元素数组索引

然后,我用了:

c = len(list)-1
for element in (reversed(list)):
    if condition(element):
        del list[c]
    c -= 1
print(list)

其中“列表”类似于[{'key1':value1'},{'key2':value2},{'key3':value3},...]

另外,您可以使用enumerate做更多的pythonic操作:

for i, element in enumerate(reversed(list)):
    if condition(element):
        del list[(i+1)*-1]
print(list)

0
arr = [1, 1, 3, 4, 5, 2, 4, 3]

# to remove first occurence of that element, suppose 3 in this example
arr.remove(3)

# to remove all occurences of that element, again suppose 3
# use something called list comprehension
new_arr = [element for element in arr if element!=3]

# if you want to delete a position use "pop" function, suppose 
# position 4 
# the pop function also returns a value
removed_element = arr.pop(4)

# u can also use "del" to delete a position
del arr[4]

0

"-v"将从数组中删除所有实例sys.argv,并且如果未找到实例,则不会发出任何投诉:

while "-v" in sys.argv:
    sys.argv.remove('-v')

您可以在名为的文件中查看运行中的代码speechToText.py

$ python speechToText.py -v
['speechToText.py']

$ python speechToText.py -x
['speechToText.py', '-x']

$ python speechToText.py -v -v
['speechToText.py']

$ python speechToText.py -v -v -x
['speechToText.py', '-x']

-1

这就是我的回答,只是使用

def remove_all(data, value):
    i = j = 0
    while j < len(data):
        if data[j] == value:
            j += 1
            continue
        data[i] = data[j]
        i += 1
        j += 1
    for x in range(j - i):
        data.pop()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.