带有回调的Python中的any()函数

时间:2010-01-06 11:39:36

标签: python functional-programming callback any

Python标准库定义了一个any()函数

  

如果iterable的任何元素为true,则返回True。如果iterable为空,则返回False。

仅检查元素是否评估为True。我希望它能够如此指定一个回调来判断一个元素是否符合以下条件:

any([1, 2, 'joe'], lambda e: isinstance(e, int) and e > 0)

8 个答案:

答案 0 :(得分:102)

怎么样:

>>> any(isinstance(e, int) and e > 0 for e in [1,2,'joe'])
True

当然,它也适用于all()

>>> all(isinstance(e, int) and e > 0 for e in [1,2,'joe'])
False

答案 1 :(得分:19)

当任何条件为True时,

任何函数都会返回True。

>>> any(isinstance(e, int) and e > 0 for e in [0 ,0, 1])
True # Returns True because 1 is greater than 0.


>>> any(isinstance(e, int) and e > 0 for e in [0 ,0, 0])
False # Returns False because not a single condition is True.

实际上,任何函数的概念来自Lisp,或者你可以从函数编程方法中说出来。还有一个与全部

相反的功能
>>> all(isinstance(e, int) and e > 0 for e in [1, 33, 22])
True # Returns True when all the condition satisfies.

>>> all(isinstance(e, int) and e > 0 for e in [1, 0, 1])
False # Returns False when a single condition fails.

如果使用得当,这两个功能真的很酷。

答案 2 :(得分:8)

你应该使用“生成器表达式” - 也就是说,一个语言结构可以使用迭代器并在一行上应用过滤器和表达式:

例如(i ** 2 for i in xrange(10))是前10个自然数(0到9)的平方的生成器

他们还允许“if”子句过滤“for”子句中的itens,因此对于您的示例,您可以使用:

any (e for e in [1, 2, 'joe'] if isinstance(e, int) and e > 0)

答案 3 :(得分:6)

Antoine P的回答略有改善

>>> any(type(e) is int for e in [1,2,'joe'])
True

all()

>>> all(type(e) is int for e in [1,2,'joe'])
False

答案 4 :(得分:5)

虽然其他人给出了很好的Pythonic答案(在大多数情况下我只是使用接受的答案),但我只是想指出如果你真的喜欢它自己实用这个功能是多么容易:

def any_lambda(iterable, function):
  return any(function(i) for i in iterable)

In [1]: any_lambda([1, 2, 'joe'], lambda e: isinstance(e, int) and e > 0
Out[1]: True
In [2]: any_lambda([-1, '2', 'joe'], lambda e: isinstance(e, int) and e > 0)
Out[2]: False

我认为我至少首先用函数参数定义它,因为它更接近匹配现有的内置函数,如map()和filter():

def any_lambda(function, iterable):
  return any(function(i) for i in iterable)

答案 5 :(得分:2)

过滤器可以工作,加上它会返回匹配的元素

>>> filter(lambda e: isinstance(e, int) and e > 0, [1,2,'joe'])
[1, 2]

答案 6 :(得分:2)

如果您真的希望保留lambda表示法,可以使用anymap的组合:

any(map(lambda e: isinstance(e, int) and e > 0, [1, 2, 'joe']))

但最好使用生成器表达式,因为它不会构建整个列表两次。

答案 7 :(得分:0)

如果确实想在任何()中内联一个lambda,你可以这样做:

>>> any((lambda: isinstance(e, int))() for e in [1,2,'joe'])
True
>>> any((lambda: isinstance(e, int))() for e in ['joe'])
False

你只需要包装未命名的lambda并确保通过附加()

在每次传递时调用它

这里的优势在于,当你遇到第一个int时,你仍然可以利用短路评估任何一个