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

c00*_*ter 44 python exception generator stopiteration

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

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

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

现在如果我改为那样i == 666,它会返回一个,StopIteration因为它找不到任何666条目a.

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

zee*_*kay 117

如果您使用的是Python 2.6+,则应使用next内置函数,而不是next方法(__next__在3.x 中替换).该next内置有一个可选的默认参数,返回如果迭代被耗尽,而不是提高StopIteration:

next((i for i, v in enumerate(a) if i == 666), None)
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的回答。但我正在使用`Python 3.6.3`,它也适用于我的项目。 (2认同)

HYR*_*YRY 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()
Run Code Online (Sandbox Code Playgroud)

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

>>> timeit.timeit("a.index(0)", "a=range(10)")
0.19335955439601094
>>> timeit.timeit("a.index(99)", "a=range(100)")
2.1938486138533335
Run Code Online (Sandbox Code Playgroud)