PythonMastery

Replace flag loops with any() and all()

any() and all() with a generator replace the found = False loop, stop at the first answer, and read like the question you're asking.

"Is any reading too hot?" and "are all orders paid?" are questions, and Python has a built-in for each. Both stop as soon as they know the answer.

Before

python
readings = [21.5, 22.0, 38.9, 21.8]

too_hot = False
for r in readings:
    if r > 35:
        too_hot = True
        break
print(too_hot)
output
True

Six lines, a flag and a break, to ask one question.

After

python
readings = [21.5, 22.0, 38.9, 21.8]

print(any(r > 35 for r in readings))
print(all(18 <= r <= 25 for r in readings))
output
True
False

They stop early

any() stops at the first true value, all() at the first false one. You can watch it happen:

python
def too_hot(r):
    print("checking", r)
    return r > 35

print(any(too_hot(r) for r in [21.5, 38.9, 22.0]))
output
checking 21.5
checking 38.9
True

22.0 is never checked. On a long list, or with a slow check, that's real time saved.

Why it works

The argument without square brackets is a generator expression: it produces one value at a time, only when asked. any() asks for the next value until it gets a true one. With square brackets, any([too_hot(r) for r in readings]), the whole list is built first and every check runs, so the short-circuit is lost.

When not to use it

Watch the empty case: any([]) is False and all([]) is True (nothing broke the rule). If "no orders" should not count as "all paid", check for emptiness first. And if you need which item matched, not just whether one did, use next((r for r in readings if r > 35), None) instead.

Learn it properly: Comprehensions: Lists, Dicts, Sets, Generators, Generators: Lazy Iteration with yield