用于 Python 的 list.index() 函数,当找不到任何内容时不会抛出异常



如果条目不存在,Python的list.index(x)将抛出异常。有没有更好的方法来做到这一点,而不需要处理异常?

如果您不关心匹配元素的位置,则使用:

found = x in somelist

如果你真的在乎,那么使用LBYL风格的条件表达式:

i = somelist.index(x) if x in somelist else None

实现自己的索引列表?

class mylist(list):
  def index_withoutexception(self,i):
    try:
        return self.index(i)
    except:
        return -1

所以,你可以使用list,并使用index2,在错误的情况下返回你想要的。

你可以这样使用:

  l = mylist([1,2,3,4,5]) # This is the only difference with a real list
  l.append(4) # l is a list.
  l.index_withoutexception(19) # return -1 or what you want

TL;DR:异常是您的朋友,也是解决上述问题的最佳方法。
请求原谅比请求允许更容易(EAFP)

OP在评论中澄清说,对于他们的用例,知道索引是什么实际上并不重要。正如公认的答案所指出的,如果你不在乎,使用x in somelist是最好的答案。

但我假设,正如最初的问题所暗示的那样,您确实关心索引是什么。在这种情况下,我会注意到所有其他解决方案都需要扫描列表两次,这会带来很大的性能损失。

此外,正如德高望重的Raymond Hettinger在评论中所写的

即使我们有list。如果发现返回-1,您仍然需要测试I == -1并采取一些操作。

因此,我将推翻原始问题中应该避免异常的假设。我建议例外是你的朋友。它们没什么好怕的,它们不是低效的,事实上,你需要熟悉它们才能写出好的代码。

所以我认为最好的答案是使用try-except方法:

try:
    i = somelist.index(x) 
except ValueError:
    # deal with it

处理它"只是意味着做你需要做的事情:将I设置为一个哨兵值,引发你自己的异常,遵循不同的代码分支,等等。

这个例子说明了为什么Python"请求原谅比请求允许更容易"(EAFP)的原则是有意义的,这与"先看后跳"(LBYL)

的if-then-else风格形成了对比。

写一个你需要的函数:

def find_in_iterable(x, iterable):
    for i, item in enumerate(iterable):
        if item == x:
            return i
    return None

如果您只需要知道项目是否存在,而不需要知道索引,您可以使用in:

x in yourlist

是的,有。你可以。执行类似的操作:

test = lambda l, e: l.index(e) if e in l else None

的工作方式是这样的:

>>> a = ['a', 'b', 'c', 'g', 'c']
>>> test(a, 'b')
1
>>> test(a, 'c')
2
>>> test(a, 't')
None

所以,基本上,test() 将返回元素的索引(第二个参数)在给定的列表(第一个参数),除非它还没有找到(在这种情况下,它将返回None,但它可以是任何你发现合适的)。

如果您不关心它在序列中的位置,只关心它的存在,那么使用in操作符。否则,编写一个函数来重构异常处理。

def inlist(needle, haystack):
  try:
    return haystack.index(needle)
  except ...:
    return -1

我喜欢使用Web2py的List类,在它的胶子包的存储模块中找到。storage模块提供了类列表(List)和类字典(storage)数据结构,当找不到元素时不会引发错误。

首先下载web2py的源代码,然后将gluon包文件夹复制粘贴到python安装的site-packages中。

现在试一下:

>>> from gluon.storage import List
>>> L = List(['a','b','c'])
>>> print L(2)
c
>>> print L(3) #No IndexError!
None

注意,它也可以表现得像一个普通列表:

>>> print L[3]
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
l[3]
IndexError: list index out of range

没有内置的方法来做你想做的。

这里有一个很好的帖子,可能会帮助你:为什么列表没有'没有安全"get"像字典一样的方法?

希望对您有所帮助

lst= ','.join('qwerty').split(',') # create list
i='a'  #srch string
lst.index(i) if i in lst else None

最新更新