any() and all()
Introduction
The any() and all() functions take an iterable and evaluate the truthiness of its elements. They are incredibly useful for writing concise conditional checks in interviews.
any()
Returns True if at least one element in the iterable evaluates to True. If the iterable is empty, it returns False.
Short-Circuit Evaluation
any() stops evaluating as soon as it finds the first True value.
def check_positive(n):
print(f"Checking {n}")
return n > 0
nums = [-1, -2, 5, -4]
# Stops printing after "Checking 5"
result = any(check_positive(x) for x in nums)
all()
Returns True if every element in the iterable evaluates to True. If the iterable is empty, it returns True.
Short-Circuit Evaluation
all() stops evaluating as soon as it finds the first False value.
nums = [1, 2, -5, 4]
# Stops evaluating when it hits -5
result = all(x > 0 for x in nums)
print(result) # False
Combining with Generator Expressions
The true power of any() and all() in interviews comes from combining them with generator expressions. This allows you to replace multi-line for loops with a single, readable line of code.
Example: Checking a Valid Sudoku Row
Instead of:
Write:
Example: Finding an Overlap
Instead of:
def has_overlap(list1, list2):
set2 = set(list2)
for x in list1:
if x in set2:
return True
return False
Write:
Time and Space Complexity
- Time Complexity: \(O(N)\) in the worst case (it must check every element). \(O(1)\) in the best case due to short-circuiting.
- Space Complexity: \(O(1)\) when used with a generator expression. (Warning: Using a list comprehension
[x > 0 for x in nums]forces \(O(N)\) space beforeany()even starts. Always use generators(...)).
Summary
- Use
any()to check if at least one condition is met. - Use
all()to check if all conditions are met. - Both functions short-circuit to save time.
- Always use them with generator expressions
(condition for item in iterable)to save space.