【问题标题】:Python equivalent of c++ find_ifPython 等效于 c++ find_if
【发布时间】:2018-12-26 21:31:41
【问题描述】:

是否有一个与std::find_if 等效的内置python 来查找给定条件为true 的列表的第一个元素?换句话说,类似于列表的index() 函数,但具有任意一元谓词,而不仅仅是相等性测试。

我不想使用列表推导,因为我想到的特定谓词计算起来有些昂贵。

【问题讨论】:

  • 您在寻找“in”命令吗?:如果 x 在列表中:做某事。
  • 你读过这个答案了吗? stackoverflow.com/a/9542768/10077 看“寻找第一次出现”。
  • 好像你想要assignment expressions... “它让我们可以方便地为any() 表达式捕获一个“证人””

标签: python syntax


【解决方案1】:

使用an answer to a related question 的提示,并借用 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 的函数:

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))

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

【讨论】:

    【解决方案2】:

    比如说,你有一些谓词函数pred 和一个列表lst。 您可以使用itertools.dropwhile 获取lst 中的第一个元素, 其中pred 返回True

    itertools.dropwhile(lambda x: not pred(x), lst).next()
    

    它会跳过所有 pred(x)False.next() 的元素 为您生成 pred(x) 为 True 的值。

    编辑:

    用于查找lst 中的第一个元素可被5 整除的示例

    >>> 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
    

    【讨论】:

    • 使用我在上面的 cmets 中链接的答案,我也能够通过 next(n for n in lst if n%5==0) 完成此操作。
    • 是的,当然,但 OP 不希望使用列表理解。
    • 那里没有列表理解。只有一个生成器表达式。
    • 嗯,我完全同意你的方法,但它们确实共享相同的语法结构。
    • 感谢您的回答;我接受了另一个,因为它是“纯”python,不需要任何导入。
    猜你喜欢
    • 2014-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 2015-03-29
    • 2011-01-23
    • 2016-08-13
    • 2012-06-28
    相关资源
    最近更新 更多