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

发布于 2024-11-30 01:50:10 字数 458 浏览 1 评论 0原文

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

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

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

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

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

I am using generators to perform searches in lists like this simple example:

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

(Just to frame the example a bit, I am using very much longer lists compared to the one above, and the entries are a little bit more complicated than int. I do it this way so the entire lists won't be traversed each time I search them)

Now if I would instead change that to i == 666, it would return a StopIteration because it can't find any 666 entry in a.

How can I make it return None instead? I could of course wrap it in a try ... except clause, but is there a more pythonic way to do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

西瑶 2024-12-07 01:50:10

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

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

If you are using Python 2.6+ you should use the next built-in function, not the next method (which was replaced with __next__ in 3.x). The next built-in takes an optional default argument to return if the iterator is exhausted, instead of raising StopIteration:

next((i for i, v in enumerate(a) if i == 666), None)
镜花水月 2024-12-07 01:50:10

您可以使用 (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

You can chain the generator with (None,):

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

but I think a.index(2) will not traverse the full list, when 2 is found, the search is finished. you can test this:

>>> timeit.timeit("a.index(0)", "a=range(10)")
0.19335955439601094
>>> timeit.timeit("a.index(99)", "a=range(100)")
2.1938486138533335
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文