找到序列中第一个匹配条件的元素

282 投票
4 回答
192005 浏览
提问于 2025-04-17 08:30

我想找一种简单的方法,来找到列表中第一个符合条件的元素。

现在的代码看起来很糟糕:

[x for x in seq if predicate(x)][0]

我考虑把它改成:

from itertools import dropwhile
dropwhile(lambda x: not predicate(x), seq).next()

但应该有更优雅的写法……如果找不到匹配的元素,返回一个None值,而不是抛出异常,那就更好了。

我知道我可以定义一个这样的函数:

def get_first(predicate, seq):
    for i in seq:
        if predicate(i): return i
    return None

但是如果代码里到处都是这种实用函数,感觉就没意思了(而且人们可能不会注意到这些函数已经存在,所以它们往往会被重复写)。如果有内置的功能可以做到这一点,那就更好了。

4 个回答

12

我觉得你提到的两个解决方案都没有问题。

不过在我自己的代码中,我会这样实现:

(x for x in seq if predicate(x)).next()

使用()的语法可以创建一个生成器,这比用[]一次性生成整个列表要更高效。

106

你可以使用生成器表达式,并设置一个默认值,然后用 next 来获取结果:

next((x for x in seq if predicate(x)), None)

不过,要使用这个一行代码,你需要确保你的Python版本是2.6或更高。

这篇相当受欢迎的文章进一步讨论了这个问题:最简洁的Python查找列表函数?

456

要在一个序列 seq 中找到第一个符合条件的元素,可以使用以下方法:

next(x for x in seq if predicate(x))

或者简单点:

Python 2

next(itertools.ifilter(predicate, seq))

Python 3

next(filter(predicate, seq))

如果没有任何元素符合条件,这些方法会抛出一个 StopIteration 的异常。


如果没有找到这样的元素,可以返回 None

next((x for x in seq if predicate(x)), None)

或者:

next(filter(predicate, seq), None)

撰写回答