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

Emi*_*nov 59 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)
Run Code Online (Sandbox Code Playgroud)

Ant*_* P. 105

怎么样:

>>> any(isinstance(e, int) and e > 0 for e in [1,2,'joe'])
True
Run Code Online (Sandbox Code Playgroud)

all()当然也适用:

>>> all(isinstance(e, int) and e > 0 for e in [1,2,'joe'])
False
Run Code Online (Sandbox Code Playgroud)

  • 不是这种类型的任何函数的问题,它将首先创建一个整体的布尔列表,然后检查一个1是真的吗?找到第一个有效的实例后,不是停止? (3认同)
  • @JoelHarkes只要您不将迭代器包装在`[]`或`list()`中,它就应使用生成器并按需工作。 (2认同)

aat*_*ifh 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.
Run Code Online (Sandbox Code Playgroud)

实际上,任何函数的概念都来自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.
Run Code Online (Sandbox Code Playgroud)

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


jsb*_*eno 8

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

例如(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)
Run Code Online (Sandbox Code Playgroud)


Soh*_*amC 6

对Antoine P的回答略有改进

>>> any(type(e) is int for e in [1,2,'joe'])
True
Run Code Online (Sandbox Code Playgroud)

对于 all()

>>> all(type(e) is int for e in [1,2,'joe'])
False
Run Code Online (Sandbox Code Playgroud)


Sha*_*umo 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
Run Code Online (Sandbox Code Playgroud)

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

def any_lambda(function, iterable):
  return any(function(i) for i in iterable)
Run Code Online (Sandbox Code Playgroud)


vol*_*ent 5

如果您确实想保留 lambda 表示法,则可以使用any和的组合,如下所示:map

any(map(lambda e: isinstance(e, int) and e > 0, [1, 2, 'joe']))
Run Code Online (Sandbox Code Playgroud)

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