找到序列中第一个匹配条件的元素
我想找一种简单的方法,来找到列表中第一个符合条件的元素。
现在的代码看起来很糟糕:
[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)