85

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

如果可迭代的任何元素为真,则返回真。如果可迭代对象为空,则返回 False。

它仅检查元素是否评估为True。我希望它能够指定一个回调来判断一个元素是否符合要求,例如:

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

8 回答 8

138

怎么样:

>>> 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
于 2010-01-06T11:43:32.287 回答
19

当任何条件为真时,任何函数都返回真。

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

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

于 2010-01-06T11:54:44.750 回答
12

您应该使用“生成器表达式” - 即可以使用迭代器并在一行上应用过滤器和表达式的语言结构:

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

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

any (e for e in [1, 2, 'joe'] if isinstance(e, int) and e > 0)
于 2010-01-06T11:45:16.010 回答
8

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
于 2014-03-14T02:20:43.613 回答
6

虽然其他人给出了很好的 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)
于 2013-11-08T20:43:45.160 回答
5

如果你真的想像这样保持你的 lambda 表示法,你可以使用any和的组合:map

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

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

于 2015-02-09T16:02:51.393 回答
4

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

>>> filter(lambda e: isinstance(e, int) and e > 0, [1,2,'joe'])
[1, 2]
于 2010-01-06T16:48:38.307 回答
3

如果你真的想在 any() 中内联一个 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 时利用短路 any 的评估

于 2017-08-01T22:22:11.103 回答