如何让Python生成器返回None而不是StopIteration?

时间:2011-08-18 03:29:35

标签: python exception generator stopiteration

我正在使用生成器在列表中执行搜索,就像这个简单的例子一样:

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

(只是为了对示例进行框架,我使用的列表与上面的列表相比要长得多,而且条目比int稍微复杂一点。我是这样做的,所以整个列表每次搜索时都不会遍历)

现在,如果我将其更改为i == 666,则会返回StopIteration,因为它无法在666中找到任何a条目。

如何让它返回None?我当然可以将它包装在一个try ... except子句中,但有更多的pythonic方法吗?

2 个答案:

答案 0 :(得分:101)

如果您使用的是Python 2.6+,则应使用next内置函数,而不是next方法(在3.x中替换为__next__)。如果迭代器已用完,next内置函数将返回一个可选的默认参数,而不是引发StopIteration

next((i for i, v in enumerate(a) if i == 666), None)

答案 1 :(得分: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