69

我正在使用生成器在列表中执行搜索,例如这个简单的示例:

>>> a = [1,2,3,4]
>>> (i for i, v in enumerate(a) if v == 4).next()
3

(只是为了举例说明,与上面的列表相比,我使用的列表要长得多,并且条目比 . 稍微复杂一些int。我这样做是为了每次我都不会遍历整个列表搜索他们)

现在,如果我改为将其更改为i == 666,它将返回 a StopIteration,因为它在 . 中找不到任何666条目a

我怎样才能让它返回None呢?我当然可以将它包装在一个try ... except子句中,但是有没有更 Pythonic 的方式来做到这一点?

4

2 回答 2

148

如果您使用的是 Python 2.6+,则应该使用next内置函数,而不是方法(在 3.xnext中已替换为)。__next__如果迭代器next用尽,内置函数采用可选的默认参数返回,而不是 raise StopIteration

next((i for i, v in enumerate(a) if i == 666), None)
于 2011-08-18T04:00:11.523 回答
7

您可以使用 (None,) 链接生成器:

from itertools import chain
a = [1,2,3,4]
print chain((i for i, v in enumerate(a) if v == 6), (None,)).next()

但我认为 a.index(2) 不会遍历完整列表,当找到 2 时,搜索完成。你可以测试一下:

>>> timeit.timeit("a.index(0)", "a=range(10)")
0.19335955439601094
>>> timeit.timeit("a.index(99)", "a=range(100)")
2.1938486138533335
于 2011-08-18T03:37:49.953 回答