Python中与c++的find_if相对应的函数是什么?

9

是否有Python内置函数相当于std::find_if,用于查找列表中第一个满足给定条件为true的元素?换句话说,类似于列表的index()函数,但是使用任意一元谓词而不仅仅是相等的测试。

我不想使用列表理解,因为我心目中特定的谓词计算起来有点昂贵。


你正在寻找“in”命令吗?:如果 x 在 list 中:做某事。 - Rob
你看过这个答案吗?https://dev59.com/FGkw5IYBdhLWcg3w8fFJ#9542768 看一下“查找第一个出现的位置”。 - Fred Larson
看起来你想要赋值表达式……“它允许我们方便地捕获any()表达式的‘证人’”。 - jonrsharpe
2个回答

11

借鉴了相关问题的答案,并参考taras发布的回答,我得出了以下结果:

>>> lst=[1,2,10,3,5,3,4]
>>> next(n for n in lst if n%5==0)
10
稍微修改一下即可得到索引而不是值:
>>> next(idx for idx,n in enumerate(lst) if n%5==0)
2

如果没有匹配,这将引发异常StopIteration。您可能希望使用一个处理异常并返回None的函数:

现在,如果没有匹配,这将引发异常StopIteration。您可能希望使用一个处理异常并返回None的函数。
def first_match(iterable, predicate):
    try:
        return next(idx for idx,n in enumerate(iterable) if predicate(n))
    except StopIteration:
        return None

lst=[1,2,10,3,5,3,4]
print(first_match(lst, lambda x: x%5 == 0))

请注意,这里使用的是生成器表达式而不是列表推导式。列表推导式会将条件应用到列表的每个成员并生成所有匹配项的列表。相比之下,该方法将其应用于每个成员,直到找到匹配项然后停止,这是解决问题的最小工作量。


嘿!我发现在lambda中使用next()的问题很有趣,所以我找了一下类似于字典.get()的默认值参数的解决方案,该参数将异常替换为默认返回值。我不知道你发布时是否已经这样做了,但是next()实际上也是这样工作的。因此,你甚至可以放弃单独的错误处理函数,并将你的解决方案简化为next((n for n in lst if n%5==0), None)。 - Larry

1
假设您有一些谓词函数pred和一个列表lst。 您可以使用itertools.dropwhile获取lst中第一个使pred返回True的元素。
itertools.dropwhile(lambda x: not pred(x), lst).next()

它跳过所有满足 pred(x)False 并且 .next() 返回的值是满足 pred(x)True 的值。 编辑: 一个示例用法是找到第一个可以被 5 整除的元素在 lst 中。
>>> import itertools
>>> lst = [1,2,10,3,5,3,4]
>>> pred = lambda x: x % 5 == 0 
>>> itertools.dropwhile(lambda x: not pred(x), lst).next()
10

使用我在上面评论中链接的答案,我也能够仅使用 next(n for n in lst if n%5==0) 完成这个任务。 - Fred Larson
是的,当然可以,但是OP不想使用列表推导式。 - taras
1
那里没有列表推导式,只有一个生成器表达式。 - Fred Larson
好的,我完全赞同你的方法,但它们确实共享相同的语法结构。 - taras
谢谢您的好回答;我接受了另一个答案,因为它是“纯”Python,不需要任何导入。 - Simon Segert
@MikeHawk,我认为被接受的答案更可信。实际上,如果将我的方法更新为返回索引而不是值,则可以在“引擎盖下”执行相同的操作。 - taras

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接