Python 标准库定义了一个any()
函数
如果可迭代的任何元素为真,则返回真。如果可迭代对象为空,则返回 False。
它仅检查元素是否评估为True
。我希望它能够指定一个回调来判断一个元素是否符合要求,例如:
any([1, 2, 'joe'], lambda e: isinstance(e, int) and e > 0)
Python 标准库定义了一个any()
函数
如果可迭代的任何元素为真,则返回真。如果可迭代对象为空,则返回 False。
它仅检查元素是否评估为True
。我希望它能够指定一个回调来判断一个元素是否符合要求,例如:
any([1, 2, 'joe'], lambda e: isinstance(e, int) and e > 0)
怎么样:
>>> 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
当任何条件为真时,任何函数都返回真。
>>> 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.
如果使用得当,这两个功能真的很酷。
您应该使用“生成器表达式” - 即可以使用迭代器并在一行上应用过滤器和表达式的语言结构:
例如(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)
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
虽然其他人给出了很好的 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)
如果你真的想像这样保持你的 lambda 表示法,你可以使用any
和的组合:map
any(map(lambda e: isinstance(e, int) and e > 0, [1, 2, 'joe']))
但最好使用生成器表达式,因为它不会构建整个列表两次。
过滤器可以工作,而且它会返回匹配的元素
>>> filter(lambda e: isinstance(e, int) and e > 0, [1,2,'joe'])
[1, 2]
如果你真的想在 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 的评估