Is the shortcircuit behaviour of Python's any/all explicit?
Solution 1:
The behaviour is guaranteed. I've contributed a patch, which was accepted and merged recently, so if you grab the latest sources you will see that the short-circuiting behaviour is now explicitly enforced.
git clone https://github.com/python/cpython.git
grep Short-circuit cpython/Lib/test/test_builtin.py
Solution 2:
The docs say
"Return True if any element of the iterable is true. If the iterable is empty, return False. EQUIVALENT TO:" (emphasis mine) ...
def any(iterable):
for element in iterable:
if element:
return True
return False
If any
didn't short circuit, it wouldn't be EQUIVALENT to the posted code since the posted code clearly short circuits. You could consume more of a generator than you want to for example. In light of that, I say that the short circuiting behavior is guaranteed.
The exact same argument could be made for all
.
Solution 3:
In case you landed here looking for "do any/all always always short-circuit?"
They do, but there is a gotcha: using a list comprehension can make it seem like you are overriding the short-circuiting behavior:
def hi():
print('hi')
return True
>>> any(hi() for num in [1, 2, 3, 4])
hi
>>> any([hi() for num in [1, 2, 3, 4]])
hi
hi
hi
hi
The list comprehension executes before any() does.
(Note: This does not answer the OP's very different question. This is the only stackoverflow page that comes up for me when searching "any all short circuit python.")
Solution 4:
It HAS to short circuit, since it could be given an unbound iterable. If it did not short circuit then this would never terminate:
any(x == 10 for x in itertools.count())