web-dev-qa-db-fra.com

En face de toute fonction ()

La fonction intégrée Python any(iterable) peut aider à vérifier rapidement si une bool(element) est True dans un type itérable.

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

Mais existe-t-il une manière élégante ou une fonction dans Python qui pourrait obtenir l'effet opposé de any(iterable)? Autrement dit, si une bool(element) is False retourne True, comme dans l'exemple suivant:

>>> l = [True, False, True]
>>> any_false(l)
>>> True
63
Ekeyme Mo

Il y a aussi la fonction all qui fait le contraire de ce que vous voulez, elle retourne True si tous sont True et False si certains sont False. Par conséquent, vous pouvez simplement faire:

not all(l)
112
Jack Aidley

Écrivez une expression de générateur qui teste votre condition personnalisée. Vous n'êtes pas lié uniquement au test par défaut véracité:

any(not i for i in l)
48
deceze

Eh bien, l'implémentation de any est équivalente à:

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

Donc, changez simplement la condition de if element à if not element:

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

Oui, bien sûr cela ne tire pas parti de la vitesse des fonctions intégrées any ou all comme les autres les réponses le font, mais c'est une belle alternative lisible.

16

Tu peux faire:

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

Rappelez-vous que map dans Python 3 est un générateur. Pour Python 2, vous voudrez probablement utiliser imap


Mea Culpa: Après avoir chronométré ces derniers, la méthode que j'ai proposée est haut la main la plus lente

Le plus rapide est not all(l) ou not next(filterfalse(bool, it), True) qui est juste une variante stupide d'itertools. Utilisez Jack Aidleys solution .

Code temporel:

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

Résultats:

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
9
dawg