我想从匹配条件的列表中获取第一个项目。重要的是,产生的方法不能处理整个列表,因为列表可能非常大。例如,以下函数就足够了:
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
但是,我想不出一个好的内置/一行程序让我这样做。如果没有必要,我并不特别想复制这个函数。有没有一种内置的方法来获取第一个匹配条件的项?
发布于 2016-02-20 03:25:41
作为一个可重用的、有文档记录和测试过的功能
def first(iterable, condition = lambda x: True):
"""
Returns the first item in the `iterable` that
satisfies the `condition`.
If the condition is not given, returns the first item of
the iterable.
Raises `StopIteration` if no item satysfing the condition is found.
>>> first( (1,2,3), condition=lambda x: x % 2 == 0)
2
>>> first(range(3, 100))
3
>>> first( () )
Traceback (most recent call last):
...
StopIteration
"""
return next(x for x in iterable if condition(x))
带有默认参数的版本
@zorf建议了此函数的一个版本,如果可迭代为空或没有匹配条件的项,则可以使用预定义的返回值:
def first(iterable, default = None, condition = lambda x: True):
"""
Returns the first item in the `iterable` that
satisfies the `condition`.
If the condition is not given, returns the first item of
the iterable.
If the `default` argument is given and the iterable is empty,
or if it has no items matching the condition, the `default` argument
is returned if it matches the condition.
The `default` argument being None is the same as it not being given.
Raises `StopIteration` if no item satisfying the condition is found
and default is not given or doesn't satisfy the condition.
>>> first( (1,2,3), condition=lambda x: x % 2 == 0)
2
>>> first(range(3, 100))
3
>>> first( () )
Traceback (most recent call last):
...
StopIteration
>>> first([], default=1)
1
>>> first([], default=1, condition=lambda x: x % 2 == 0)
Traceback (most recent call last):
...
StopIteration
>>> first([1,3,5], default=1, condition=lambda x: x % 2 == 0)
Traceback (most recent call last):
...
StopIteration
"""
try:
return next(x for x in iterable if condition(x))
except StopIteration:
if default is not None and condition(default):
return default
else:
raise
发布于 2010-03-02 15:27:51
与使用ifilter
类似,您可以使用生成器表达式:
>>> (x for x in xrange(10) if x > 5).next()
6
在这两种情况下,您都可能希望捕获StopIteration
,以防没有元素满足您的条件。
从技术上讲,我认为你可以这样做:
>>> foo = None
>>> for foo in (x for x in xrange(10) if x > 5): break
...
>>> foo
6
它可以避免创建try/except
块。但这对语法来说似乎有些晦涩和滥用。
发布于 2010-03-02 16:22:09
我会写这篇文章
next(x for x in xrange(10) if x > 3)
https://stackoverflow.com/questions/2361426
复制相似问题