Opposite of any() function
Question:
The Python built-in function any(iterable)
can help to quickly check if any bool(element)
is True
in a iterable type.
>>> l = [None, False, 0]
>>> any(l)
False
>>> l = [None, 1, 0]
>>> any(l)
True
But is there an elegant way or function in Python that could achieve the opposite effect of any(iterable)
? That is, if any bool(element) is False
then return True
, like the following example:
>>> l = [True, False, True]
>>> any_false(l)
>>> True
Answers:
Write a generator expression which tests your custom condition. You’re not bound to only the default truthiness test:
any(not i for i in l)
There is also the all
function which does the opposite of what you want, it returns True
if all are True
and False
if any are False
. Therefore you can just do:
not all(l)
Well, the implementation of any
is equivalent to:
def any(iterable):
for element in iterable:
if element:
return True
return False
So, just switch the condition from if element
to if not element
:
def reverse_any(iterable):
for element in iterable:
if not element:
return True
return False
Yes, of course this doesn’t leverage the speed of the built-ins any
or all
like the other answers do, but it’s a nice readable alternative.
You can do:
>>> l = [True, False, True]
>>> False in map(bool, l)
True
Recall that map
in Python 3 is a generator. For Python 2, you probably want to use imap
Mea Culpa: After timing these, the method I offered is hands down the slowest
The fastest is not all(l)
or not next(filterfalse(bool, it), True)
which is just a silly itertools variant. Use Jack Aidleys solution.
Timing code:
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) )
Results:
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
The Python built-in function any(iterable)
can help to quickly check if any bool(element)
is True
in a iterable type.
>>> l = [None, False, 0]
>>> any(l)
False
>>> l = [None, 1, 0]
>>> any(l)
True
But is there an elegant way or function in Python that could achieve the opposite effect of any(iterable)
? That is, if any bool(element) is False
then return True
, like the following example:
>>> l = [True, False, True]
>>> any_false(l)
>>> True
Write a generator expression which tests your custom condition. You’re not bound to only the default truthiness test:
any(not i for i in l)
There is also the all
function which does the opposite of what you want, it returns True
if all are True
and False
if any are False
. Therefore you can just do:
not all(l)
Well, the implementation of any
is equivalent to:
def any(iterable):
for element in iterable:
if element:
return True
return False
So, just switch the condition from if element
to if not element
:
def reverse_any(iterable):
for element in iterable:
if not element:
return True
return False
Yes, of course this doesn’t leverage the speed of the built-ins any
or all
like the other answers do, but it’s a nice readable alternative.
You can do:
>>> l = [True, False, True]
>>> False in map(bool, l)
True
Recall that map
in Python 3 is a generator. For Python 2, you probably want to use imap
Mea Culpa: After timing these, the method I offered is hands down the slowest
The fastest is not all(l)
or not next(filterfalse(bool, it), True)
which is just a silly itertools variant. Use Jack Aidleys solution.
Timing code:
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) )
Results:
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