【问题标题】:Python list.index throws exception when index not foundPython list.index 在找不到索引时抛出异常
【发布时间】:2010-10-15 00:36:16
【问题描述】:

为什么 list.index 会抛出异常,而不是使用任意值(例如,-1)?这背后的想法是什么?

在我看来,处理特殊值比处理异常更简洁。

编辑:我没有意识到-1 是一个潜在的有效值。尽管如此,为什么不做其他事情呢?值 None 怎么样?

【问题讨论】:

  • 只有一条评论:每个人都说 -1 是一个有效的索引,这是真的,但这并不意味着它仍然不能用于 index() 的“未找到”结果。它不像 index() 会ever 在正常操作中返回 -1。我发现我必须编写一个完整的 try...except 块,并吸收处理异常的开销以处理不一定必然是错误条件的情况,这让我感到沮丧。

标签: python indexing list


【解决方案1】:

因为-1 本身就是一个有效的索引。它可以使用不同的值,例如None,但这没有用,-1 可以在其他情况下使用(因此 str.find()),并且仅相当于错误检查,这正是例外情况。

【讨论】:

    【解决方案2】:

    嗯,特殊值实际上必须是 None,因为 -1 是有效索引(表示列表的最后一个元素)。

    您可以通过以下方式模拟此行为:

    idx = l.index(x) if x in l else None
    

    【讨论】:

    • 好吧,就是这样或尝试/除外。
    • 有时似乎已经编写了 Python,因此您为最简单的事情编写尽可能多的代码。感谢您的回答!
    【解决方案3】:

    补充 Devin 的回答:这是特殊返回值与异常之间的老辩论。许多编程专家更喜欢异常,因为在异常时,我可以看到整个堆栈跟踪并立即推断出什么是错误的。

    【讨论】:

    • 这就是我想知道的:特殊返回值与异常。
    • +1:异常不依赖于某些值被“神圣”。异常通常更容易处理。
    • 恐异常的人可能会争辩说index 找不到对象不是错误,异常应该只用于错误。在这种情况下,我是例外。异常可以更快,因为它们不必检查成功。由于这个原因,Python 在许多情况下更喜欢异常。换句话说,如果index 找到一个对象,则继续执行而不进行条件检查。如果index 什么也没找到,你会被扔进catch 块,没有任何检查。
    • 最后一条评论忽略了底层函数当然需要检查使其失败的条件这一事实。对特殊值的额外检查可以忽略不计。更大的问题确实是如果没有找到任何东西是一个错误。这当然取决于用例。然而,这是一个低级函数,不应该强制任何特定用途,因为它必须依赖缓慢的异常处理,因此这显然是糟糕的设计,因为唯一的选择是重新实现它或使用更多降低性能的技术就像先检查 count 一样。
    【解决方案4】:

    “异常值与错误值”的争论部分是关于代码清晰度的。考虑带有错误值的代码:

    idx = sequence.index(x)
    if idx == ERROR:
        # do error processing
    else:
        print '%s occurred at position %s.' % (x, idx)
    

    错误处理最终被塞进我们的算法中间,从而使程序流程变得模糊。另一方面:

    try:
        idx = sequence.index(x)
        print '%s occurred at position %s.' % (x, idx)
    except IndexError:
        # do error processing
    

    在这种情况下,代码量实际上是相同的,但主要算法不会被错误处理破坏。

    【讨论】:

      【解决方案5】:

      主要是为了保证尽快发现错误。例如,考虑以下情况:

      l = [1, 2, 3]
      x = l.index("foo")  #normally, this will raise an error
      l[x]  #However, if line 2 returned None, it would error here
      

      您会注意到,如果 index 返回 None,则会在 l[x] 而不是 x = l.index("foo") 处引发错误。在这个例子中,这并不是什么大问题。但是想象一下,第三行在百万行程序中的某个完全不同的位置。这可能会导致一些调试噩梦。

      【讨论】:

        【解决方案6】:

        在 Python 中,-1 是一个有效的索引,表示从列表末尾(而不是开头)开始的数字,所以如果你要这样做

        idx = mylist.index(someval)
        nextval = mylist[idx+1]
        

        然后你会得到数组的第一个值,而不是意识到有一个错误。这样你就可以捕获异常并处理它。如果您不想要异常,请事先检查:

        if someval in mylist:
            idx = mylist.index(someval)
        

        编辑:返回None没有任何意义,因为如果你要测试None,你不妨测试该值是否在上面的列表中!

        【讨论】:

          【解决方案7】:

          我同意 Devin Jeanpierre 的观点,并补充说,在小例子中处理特殊值可能看起来不错,但是(除了一些值得注意的例外,例如 FPU 中的 NaN 和 SQL 中的 Null)它的扩展性几乎没有那么好。它唯一有效的地方是:

          • 您通常有很多嵌套的同构处理(例如数学或 SQL)
          • 您不关心区分错误类型
          • 你不在乎错误发生在哪里
          • 这些操作是纯函数,没有副作用。
          • 可以在更高级别为失败赋予合理的含义(例如“没有匹配的行”)

          【讨论】:

            【解决方案8】:

            一个简单的想法:-1 完全可以用作索引(与其他负值一样)。

            【讨论】:

              【解决方案9】:

              这是一个语义参数。如果你想知道一个元素的索引,你就声称它已经存在于列表中。如果你想知道它是否存在,你应该使用in

              【讨论】:

              • ...如果您声称它存在异常是处理它的正确方法。
              【解决方案10】:
              def GetListIndex(list, searchString):
                  try:
                      return list.index(searchString)
              
                  except ValueError:
                      return False
              
                  except Exception:
                      raise
              

              【讨论】:

                猜你喜欢
                • 2012-01-02
                • 2011-12-15
                • 1970-01-01
                • 1970-01-01
                • 2023-04-06
                • 1970-01-01
                • 2013-05-24
                • 2012-09-20
                • 1970-01-01
                相关资源
                最近更新 更多