从符合条件的可迭代对象中获取第一项

新手上路,请多包涵

我想从符合条件的列表中获取第一项。重要的是生成的方法不会处理可能非常大的整个列表。例如,以下功能就足够了:

 def first(the_iterable, condition = lambda x: True):
    for i in the_iterable:
        if condition(i):
            return i

这个函数可以像这样使用:

 >>> first(range(10))
0
>>> first(range(10), lambda i: i > 3)
4

但是,我想不出一个好的内置/单线让我这样做。如果不需要的话,我并不是特别想复制这个函数。有没有内置的方法来获取第一个符合条件的项目?

原文由 Chris Phillips 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 335
2 个回答

Python 2.6+ 和 Python 3:

如果您希望在未找到匹配元素时引发 StopIteration

 next(x for x in the_iterable if x > 3)

如果你想返回 default_value (例如 None ):

 next((x for x in the_iterable if x > 3), default_value)

请注意,在这种情况下,您需要在生成器表达式周围加上一对额外的括号——只要生成器表达式不是唯一的参数,就需要它们。

我看到大多数答案坚决忽略 next 内置的,所以我假设出于某种神秘的原因,他们 100% 专注于版本 2.5 和更早的版本——没有提到 Python 版本问题(但后来我在 确实 提到了 next 的答案中没有看到这一点 - 内置,这就是为什么我认为有必要自己提供一个答案 - 至少“正确版本”问题记录在案方法;-)。

Python <= 2.5

.next() 迭代器的方法立即引发 StopIteration 如果迭代器立即完成 - 即,对于您的用例,如果迭代器中没有项目满足条件。如果您不在乎(即,您知道 必须 至少有一个令人满意的项目),那么只需使用 .next() (最好在 genexp 上,为 next 内置的行Python 2.6 及更高版本)。

如果您 确实 在意,将事物包装在您最初在 Q 中指出的函数中似乎是最好的,虽然您提出的函数实现很好,但您也可以使用 itertoolsfor...: break 循环,或 genexp,或 try/except StopIteration 作为函数的主体,如各种答案所建议的那样。这些替代方案中的任何一个都没有太多附加值,因此我会选择您首先提出的极其简单的版本。

原文由 Alex Martelli 发布,翻译遵循 CC BY-SA 4.0 许可协议

该死的异常!

我喜欢 这个答案。但是,由于 next() 在没有项目时引发 StopIteration 异常,我将使用以下代码段来避免异常:

 a = []
item = next((x for x in a), None)


例如,

 a = []
item = next(x for x in a)

将引发 StopIteration 异常;

 Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

原文由 Jossef Harush Kadouri 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题