任何()函数的对立面

Python 内置函数 any(iterable)可以帮助快速检查在可迭代类型中是否有 bool(element)True

>>> l = [None, False, 0]
>>> any(l)
False
>>> l = [None, 1, 0]
>>> any(l)
True

但是在 Python 中是否有一种优雅的方法或函数可以实现 any(iterable)的相反效果?也就是说,如果有 bool(element) is False,那么返回 True,如下例所示:

>>> l = [True, False, True]
>>> any_false(l)
>>> True
27785 次浏览

编写一个生成器表达式来测试您的自定义条件:

any(not i for i in l)

还有一个 all函数,它的作用与你想要的相反,如果所有函数都是 True,那么它返回 True; 如果有 False,那么返回 False。因此你可以这样做:

not all(l)

那么 any的实现是 等效到:

def any(iterable):
for element in iterable:
if element:
return True
return False

因此,只需将条件从 if element切换到 if not element:

def reverse_any(iterable):
for element in iterable:
if not element:
return True
return False

是的,当然这不利用内置的 anyall的速度像其他答案一样,但它是一个很好的可读的替代品。

你可以这样做:

>>> l = [True, False, True]
>>> False in map(bool, l)
True

回想一下,Python3中的 map是一个生成器,对于 Python2,您可能需要使用 imap


我的过失: 在计时之后,我提供的方法是毫无疑问的 最慢的

最快的是 not all(l)not next(filterfalse(bool, it), True),它只是一个愚蠢的迭代工具变种。使用杰克艾德利 解决方案

计时码:

from itertools import filterfalse


def af1(it):
return not all(it)


def af2(it):
return any(not i for i in it)


def af3(iterable):
for element in iterable:
if not element:
return True
return False


def af4(it):
return False in map(bool, it)


def af5(it):
return not next(filterfalse(bool, it), True)


if __name__=='__main__':
import timeit
for i, l in enumerate([[True]*1000+[False]+[True]*999, # False in the middle
[False]*2000, # all False
[True]*2000], # all True
start=1):
print("case:", i)
for f in (af1, af2, af3, af4, af5):
print("   ",f.__name__, timeit.timeit("f(l)", setup="from __main__ import f, l", number=100000), f(l) )

结果:

case: 1
af1 0.45357259700540453 True
af2 4.538436588976765 True
af3 1.2491040650056675 True
af4 8.935278153978288 True
af5 0.4685744970047381 True
case: 2
af1 0.016299808979965746 True
af2 0.04787631600629538 True
af3 0.015038023004308343 True
af4 0.03326922300038859 True
af5 0.029870904982089996 True
case: 3
af1 0.8545824179891497 False
af2 8.786235476000002 False
af3 2.448748088994762 False
af4 17.90895140200155 False
af5 0.9152941330103204 False