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