当我尝试从列表中删除元素时,如何忽略 ValueError?
Posted
技术标签:
【中文标题】当我尝试从列表中删除元素时,如何忽略 ValueError?【英文标题】:How can I ignore ValueError when I try to remove an element from a list? 【发布时间】:2012-04-12 12:10:37 【问题描述】:如果在x
不在列表a
中时调用a.remove(x)
,我如何忽略“不在列表中”错误消息?
这是我的情况:
>>> a = range(10)
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a.remove(10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: list.remove(x): x not in list
>>> a.remove(9)
【问题讨论】:
为什么 Python 列表中没有 Python set's discard operation?discard
从集合中移除元素(如果存在)。
【参考方案1】:
一个好的和线程安全的方法是尝试它并忽略异常:
try:
a.remove(10)
except ValueError:
pass # do nothing!
【讨论】:
【参考方案2】:我个人会考虑使用set
而不是list
,只要元素的顺序不一定重要。然后就可以使用discard方法了:
>>> S = set(range(10))
>>> S
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> S.remove(10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 10
>>> S.discard(10)
>>> S
set([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
【讨论】:
在不合适的情况下使用set
可能会产生意想不到的后果。从文档中,Remove the first item from the list whose value is x. It is an error if there is no such item.
OP 可能只想删除其他用例中的第一项,表示列表中的有效重复项。【参考方案3】:
作为忽略ValueError
的替代方法
try:
a.remove(10)
except ValueError:
pass # do nothing!
我认为以下内容更简单易读:
if 10 in a:
a.remove(10)
【讨论】:
这是个好主意,但正如@Niklas B. 指出的那样,他是“线程安全的”,因为无论如何,10 不存在只会导致 caught i> 例外。而在这个答案中,a
可以在检查if
条件和调用.remove()
之间从a
中删除,从而导致未捕获 ValueError
。 (如果您可以保证a
不会被其他任何东西修改,那么这很好,但有了接受的答案,您甚至不必考虑这种可能性。)
对于 lambda 表达式,有时为同一目的使用单行代码会很有帮助,在这种情况下,a in 10 and a.remove(10)
可以完成这项工作。不过它也不是线程安全的。
在这个问题上有点撕裂......你什么时候放弃zen of python以保证线程安全?当然,如果您正在编写一个可能在多线程应用程序中使用的库模块,您将需要使事情变得更复杂和/或记录其线程安全(或缺乏线程安全),但一般应该尝试这样做吗?
@reteptilian 我认为这实际上不是“线程安全”而不是“Easier to ask for forgiveness than permission.”
如果您关心线程安全,您应该使用显式锁定。【参考方案4】:
更好的方法是
source_list = list(filter(lambda x: x != element_to_remove,source_list))
因为在一个更复杂的程序中,ValueError
的异常也可能会引发其他问题,这里的一些答案只是通过它,从而丢弃它,同时产生更多可能的问题。
【讨论】:
【参考方案5】:您输入了错误的输入。 语法:list.remove(x)
并且 x 是您列表的元素。 在删除括号中输入列表中已有的内容。 例如:a.remove(2)
我输入了 2,因为它在列表中。 希望这些数据对您有所帮助。
【讨论】:
问题是关于如何在尝试从列表中删除不在列表中的内容时忽略错误。【参考方案6】:列表理解怎么样?
a = [x for x in a if x != 10]
【讨论】:
请解释为什么认为这是对公认答案的改进。 @Melvyn,我主要提供它作为替代方案,不一定是“改进”。我喜欢它是一行且可读的。 这会创建一个新列表,这比修改现有列表效率低,尤其是如果找不到该项目并且不需要复制元素。跨度> 此外,它可能会破坏对现有列表的引用,例如a = ['foo']; b = a; a = [x for x in a if x != 'bar']; a.append('baz'); print(b)
将打印 ['foo']
而使用 remove
将打印 ['foo', 'baz']
。因此,我认为这不是try/remove/except
或if/in/remove
的可行通用替代方案。【参考方案7】:
当我只想确保条目不在列表、字典或集合中时,我会像这样使用 contextlib:
import contextlib
some_list = []
with contextlib.suppress(ValueError):
some_list.remove(10)
some_set = set()
some_dict = dict()
with contextlib.suppress(KeyError):
some_set.remove('some_value')
del some_dict['some_key']
【讨论】:
【参考方案8】:我认为最简单的方法(可能不是最好的方法)是写下 if 语句来检查该值是否在列表中,然后将其从列表中删除。
if 10 in a:
a.remove(10)
【讨论】:
以上是关于当我尝试从列表中删除元素时,如何忽略 ValueError?的主要内容,如果未能解决你的问题,请参考以下文章
当我尝试从网页添加 DOM 元素时,我的数组得到 0 值,如何将值添加到 .each 函数中的列表?
Python:如何在迭代列表时从列表中删除元素而不跳过未来的迭代