【问题标题】:How can I ignore ValueError when I try to remove an element from a list?当我尝试从列表中删除元素时,如何忽略 ValueError?
【发布时间】: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 operationdiscard 从集合中移除元素(如果存在)。

标签: python list error-handling elements


【解决方案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])
    

    【讨论】:

    【解决方案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/exceptif/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)
        

        【讨论】:

          猜你喜欢
          • 2020-08-08
          • 2011-10-06
          • 1970-01-01
          • 1970-01-01
          • 2021-10-18
          • 1970-01-01
          • 2019-03-09
          • 1970-01-01
          • 2019-05-12
          相关资源
          最近更新 更多