ChatGPT解决这个技术问题 Extra ChatGPT

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

如果列表中存在一个值(它可能不存在),我想从列表中删除它。

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)

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

您计算列表中 6 的索引。但是 6 不在您的列表中……那么应该发生什么? :)
这与删除列表中的值无关,因为您的代码没有到达 del 语句。也许您应该将其重新命名为“我如何获取不在列表中的值的索引。显而易见的答案 - 你不能。
@Dave好吧,不是真的。他想从列表中删除一个项目,无论它是否存在,而不是获取不存在项目的索引。这个问题问得很好。
题外话,但a bare except is bad practice。至少使用 except Exception

M
Mateen Ulhaq

要删除元素的第一次出现,请使用 list.remove

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

要删除元素的所有出现,请使用 list comprehension

>>> xs = ['a', 'b', 'c', 'd', 'b', 'b', 'b', 'b']
>>> xs = [x for x in xs if x != 'b']
>>> print(xs)
['a', 'c', 'd']

如果元素不在列表中,则失败。 :)
即使元素不在列表中,@ibz 列表理解也不会失败,是吗?
为了澄清任何略读的人,它“失败”是因为它引发了一个 ValueError 异常。
列表理解会更改列表引用,因此如果某处有引用的副本,则不会随之删除。
我不知道为什么它应该大于或小于 O(n)。我认为它使用了普通的搜索算法。没有关于任何列表排序的附加信息!
D
Dave Webb

通常,如果你告诉它做一些它不能做的事情,Python 会抛出一个异常,所以你必须这样做:

if c in a:
    a.remove(c)

或者:

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

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


预防胜于治疗。如果您可以先检查异常情况(示例 a),您应该这样做。
虽然这在其他语言中是正确的,但在 Python 中,“请求宽恕比请求许可更容易”。 docs.python.org/2/glossary.html#term-eafp
@Gusdor:如果列表在线程之间共享,那么尽管 if c in a 检查,a.remove(c) 仍可能失败(a 可以在 c in a 检查之后但在 a.remove(c) 调用之前在另一个线程中修改)。 try/except 或锁可用于避免竞争条件。
@JFSebastian 如果在线程之间共享列表并且您没有应用关键部分,那么您会遇到更大的问题。
@Gusdor,Pythonique 习惯用法是尝试不检查并在发生异常时捕获异常。它更有效(只有一个查找而不是两个),尽管有点难看
Y
YOU

你可以做

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

但上面需要在列表中搜索 6 2 次,所以尝试 except 会更快

try:
    a.remove(6)
except:
    pass

S
Sociopath

考虑:

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

要取出所有出现的情况,您可以使用 python 中的过滤器功能。例如,它看起来像:

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

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

只需取出其中一项使用

a.remove(2)

为什么将 filter() 包装在另一个 list() 中?根据手册,它已经返回了一个列表。
@OlafDietsche 在 Python 3.x 中,它返回一个过滤器对象(在 2.x 中,它返回一个列表),所以我必须将“a”转换为一个列表才能使其具有任何功能。
j
jfs

以下是如何就地执行它(没有列表理解):

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

非常聪明-我真的很喜欢这个-不幸的是,它似乎与最受欢迎的答案一样低效。 gil 的解决方案对于只出现几次您希望删除的值的巨型列表实际上要快得多。
@Larold最快的方法是一个单独的问题。在一般情况下,我的钱在清单上。如果值在输入列表中频繁出现并且不使用列表推导,则此解决方案应该执行得非常好。在 Cython 中尝试 Pypy,numpy 数据。 [@Gill 的答案是 O(n*n) 不必要(比较 1e6 和 1e12 - 你不想冒后者的风险)。 while 1: L.remove(value) 和返回 ValueError 可能适用于 CPython 中的几个 value 或小列表。
F
Felk

正如许多其他答案所述,list.remove() 将起作用,但如果该项目不在列表中,则抛出 ValueError。在 python 3.4+ 中,有一个有趣的方法来处理这个问题,使用 suppress contextmanager

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

g
gil

如果你知道要删除什么值,这里有一个简单的方法(无论如何我能想到的简单):

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

您将获得 [0, 0, 2, 3, 4]


为什么不使用 while 1 in a: 作为循环结构?
这是 O(n^2),其中的理解是 O(n)
当然@MadPhysicist 是对的,而且TerminalDilettante 的版本更加pythonic,即使我们不关心性能。 2013 年我刚刚开始学习 Python,而现在我常常为我当时写的东西感到羞耻。
然而,这会在不复制列表的情况下更改列表,这在特定情况下可能是可取的。
A
Andrey Topoleov

在一行中:

a.remove('b') if 'b' in a else None

有时它很有用。

更容易:

if 'b' in a: a.remove('b')

G
GreenAsJade

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

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

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

没有错误。

通常,列表只是一个方便的容器,用于存放实际上无序的项目。有一些问题询问如何从列表中删除所有出现的元素。如果您一开始就不想受骗,那么一套再次派上用场。

my_set.add(3)

不会从上面更改 my_set 。


P
Pagol

如果你的元素是不同的,那么一个简单的设置差异就可以了。

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]

如果您的元素是不同的并且您不关心顺序。
C
Chase Adams

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

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

如果你这样做,你真的应该只在 except ValueErrorbreak
佚名

在列表中查找一个值,然后删除该索引(如果它存在)更容易通过使用列表的 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

S
SuperNova

我们也可以使用 .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]
>>> 

S
Stefan

这里的许多答案都涉及创建一个新列表。这涉及将旧列表中的所有数据复制到新列表(删除的项目除外)。如果您的清单很大,您可能负担不起(或者您不应该这样做)。

在这些情况下,更改列表的速度要快得多。如果您必须从列表中删除超过 1 个元素,则可能会很棘手。假设您遍历列表并删除一个项目,然后列表更改并且标准 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 statement 放入循环中即可:

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]

u
user7970984

使用 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

R
Ravikiran D
 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)

没有使用过滤功能
k
kilojoules

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

>>> 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]

A
Ani Menon

nums 是列表并且 c 是要删除的值时:

要删除列表中第一次出现的 c,只需执行以下操作:

if c in nums:
    nums.remove(c)

要从列表中删除所有出现的 c,请执行以下操作:

while c in nums:
    nums.remove(c)

添加异常处理将是最佳实践,但我主要想展示如何从列表中删除所有出现的元素。


K
Krohnus Melavea

例如,我们想从 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 版本中编写的,因此您可能需要针对旧版本进行调整。


一般来说,列表理解不应该只用于副作用,在这种情况下 - 从另一个列表中删除元素。最好只使用常规循环并避免不必要的额外列表创建
B
Brijesh Kushwaha
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]

M
Mike Slinn

这会从数组 sys.argv 中删除 "-v" 的所有实例,如果没有找到实例,则不会抱怨:

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']

D
David Martínez

也许您的解决方案适用于整数,但它不适用于我的字典。

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

另一方面,“del”也没有正常工作。就我而言,使用 python 3.6:当我尝试使用“del”命令从“for”bucle 中的列表中删除一个元素时,python 会更改进程中的索引,并且 bucle 会提前停止。它仅在您以相反的顺序逐个删除元素时才有效。通过这种方式,您在浏览时不会更改待处理元素数组索引

然后,我使用:

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

其中 'list' 类似于 [{'key1':value1'},{'key2':value2}, {'key3':value3}, ...]

你也可以使用枚举做更多的pythonic:

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

g
guoxy2016

这是我的答案,只需使用 while 和 for

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()

M
Muhammad Yasirroni

一些最简单方法的基准测试:

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

S
S. Nick

这是一个效率较低的解决方案,但它仍然有效:

a = [ ] // 那是你的清单

b // 您需要删除的元素

counter = a.count(b)

while counter > 0:
    if b in a:
       a.remove(b)
       counter -= 1

print(a)