Python 与任何()函数相反

Python 与任何()函数相反,python,python-3.x,iterable,Python,Python 3.x,Iterable,Python内置函数any(iterable)可以帮助快速检查iterable类型中是否有bool(element)为True >>> l = [None, False, 0] >>> any(l) False >>> l = [None, 1, 0] >>> any(l) True 但是Python中是否有一种优雅的方式或函数可以达到与any(iterable)相反的效果呢?也就是说,如果任何bool(元素)为False

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

>>> l = [None, False, 0]
>>> any(l)
False
>>> l = [None, 1, 0]
>>> any(l)
True
但是Python中是否有一种优雅的方式或函数可以达到与
any(iterable)
相反的效果呢?也就是说,如果任何
bool(元素)为False
,则返回
True
,如以下示例所示:

>>> l = [True, False, True]
>>> any_false(l)
>>> True

编写一个测试自定义条件的生成器表达式。您不仅限于默认的真实性测试:


还有一个
all
函数,它的作用与您想要的相反,它返回
True
如果all是
True
False
如果有
False
。因此,您只需执行以下操作:

not all(l)

嗯,
any
的实现是:

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

def reverse_any(iterable):
    for element in iterable:
        if not element:
            return True
    return False
是的,当然这不会像其他答案那样利用内置的
any
all
的速度,但这是一个很好的可读性选择。

您可以:

>>> l = [True, False, True]
>>> False in map(bool, l)
True
回想一下,Python 3中的
map
是一个生成器。对于Python2,您可能希望使用
imap


罪过:在计时之后,我提供的方法是最慢的

最快的是
notall(l)
notnext(filterfalse(bool,it),True)
,这只是一个愚蠢的itertools变体。使用杰克·艾德利

定时代码:

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

是的,可能是
any(bool(i)=False,因为l中的i)
更好。对吧?
None==False
False
,但我不希望这样
bool(None)=False
True
在这种情况下,
非i for i In l
可能是最好的。@EkeymeMo避免使用
=
与布尔值进行比较。只需使用裸值,例如,
if值:…
。但是,如果您必须检查对象是否为布尔值而不是真实值,请使用
is
。否则您可能会得到意外的结果——例如,
1==True
为True,但
2==True
为false。这比
要慢得多。并非所有(l)
@Barmar
all
在遇到
false
时都会短路;我假设硬编码的C风格检查
False
比生成器中的Python
noti
简单得多……如果iterable为空,则不确定OP想要什么,但值得注意的是,
all
在iterable为空时返回True。@Lafexlos很好,始终值得考虑端点。我猜
[]
错误
是正确的答案;这段代码给出了什么,但是OP必须指定。对于
all(…)
,您始终可以将
True
添加到参数列表中,而无需更改输出
True
是一个“中性元素”(就像0表示加法,1表示乘法是中性元素一样)。这就是为什么empty
all()
返回
True
。对于
any()
来说,中性元素是
False
@Fermiparadox:进行一些快速计时,这比
any
方法要快得多,因为它都是内置的。然而,Deceze的方法更普遍适用。+1从长远来看,一点数理逻辑知识可以节省大量时间:
∃x:x
相当于
(∀x:x)
。看@JackAidley当然是了,我从来没有做出过其他的断言。我刚刚添加了一个替代方案。请记住,
any
all
对新用户来说通常都很神秘,查看它们的大致实现通常会有所帮助。杰克·艾德利已经正确回答了您的问题。你可能想检查它背后的理论。杰凯德利和德塞兹的答案都会根据你的问题而有所帮助。请注意,“any element is falsy”与“no element is truthy”不同-它们对空数组有不同的答案。“请注意,
all
在空iterable上返回
True
”。你有别的想法吗?@Bergi Nope,我只是想让一些flash用户注意到这个有趣的功能。我的话有什么不对吗?@EkeymeMo:Dunno,听起来像是警告,好像是要避免什么。也许只是我。
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