是否有内置的Python函数在将函数映射到iterable时会返回第一个True-ish值?

时间:2015-05-19 16:00:24

标签: python

这是我的意思,我经常这么做,所以也许我只是重新实现了一个我没见过的内置:

import itertools
def first(fn, *args):
    for x in itertools.chain(*args):
        value = fn(x)
        if value: return value

# Example use:
example = {'answer': 42, 'bring': 'towel'}
print first(example.get, ['dolphin', 'guide', 'answer', 'panic', 'bring'])
# Prints 42

Python是否允许我使用内置函数执行此操作?

3 个答案:

答案 0 :(得分:3)

您基本上希望在序列上映射filter,并获得第一个true-ish值。为此,您可以将next与默认过滤器功能一起使用,并使用>>> example = {'answer': 42, 'bring': 'towel'} >>> lst = ['dolphin', 'guide', 'answer', 'panic', 'bring'] >>> next(filter(None, map(example.get, lst))) 42 获取第一个:

{{1}}

在Python 3中,所有这些都是懒惰的,因此整个序列不会被迭代。在Python 2中,您可以使用itertools来获取内置类型的惰性版本,imapifilter

答案 1 :(得分:2)

你可以使用next()内置和生成器表达式:

next(example[key] 
        for key in ['dolphin', 'guide', 'answer', 'panic', 'bring'] 
        if key in example)

如果你想使用预定义函数,最好使用filter,它接受函数作为第一个参数(示例中为lambda):

next(itertools.ifilter(lambda txt: 'a' in txt, ['foo', 'bar']))

答案 2 :(得分:0)

我认为没有内置功能来做你想做的事。有一种可以说更多的Pythonic方式来做你正在做的事情:

example = {'answer': 42, 'bring': 'towel'}
keys = ['dolphin', 'guide', 'answer', 'panic', 'bring']
print filter(lambda x: x, map(example.get, keys))[0]

这种方法的缺点是它将遍历整个列表,而不是在第一个值处突破。您还必须添加额外的检查以确保列表不空。