For a list or other reusable collection, call Python’s built-in max() and min() on the values. If you must process a one-pass iterator, track both extremes in one loop so the first calculation does not consume the input.
Use max() and min() for a collection
Pass the iterable as the single argument to each function:
numbers = [12, -4, 7, 0]
largest = max(numbers)
smallest = min(numbers)
print(largest) # 12
print(smallest) # -4
max(iterable) returns the largest item, while min(iterable) returns the smallest. Each function can also compare two or more positional arguments directly; when you want to search a collection, pass that collection as one iterable argument. See the Python 3.13.16 built-in functions documentation.
Handle empty input and ties
If the iterable is empty, either function raises ValueError unless you provide default. When empty input is possible, choose a meaningful fallback or check for emptiness first; an arbitrary numeric default can be mistaken for a genuine result.
#1 Best Overall
numbers = []
if numbers:
largest = max(numbers)
smallest = min(numbers)
else:
largest = None
smallest = None
When several items tie for an extreme, Python returns the first one encountered. This matters especially when the items are records rather than plain numbers.
Choose an extreme by a record field with key=
The optional key argument supplies a one-argument function that determines how items are compared. The function returns the original selected item, not the comparison value:
Rank #2
people = [
{"name": "Mina", "score": 84},
{"name": "Leo", "score": 91},
{"name": "Ari", "score": 76},
]
highest_score = max(people, key=lambda person: person["score"])
lowest_score = min(people, key=lambda person: person["score"])
print(highest_score["name"]) # Leo
print(lowest_score["name"]) # Ari
The comparison uses each person’s score, while the result remains the corresponding dictionary. The same empty-input and tie behavior applies to these calls.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Track both values in one loop for a stream
An iterator can be consumed as a function reads it. Calling max() and then min() on the same one-pass iterator does not make both functions inspect the same complete input. For a stream, initialize the extrema from the first value and update them as each subsequent value arrives:
Recommended Free Tools
def find_extremes(values):
iterator = iter(values)
try:
first = next(iterator)
except StopIteration:
return None, None # No values were supplied
largest = smallest = first
for value in iterator:
if value > largest:
largest = value
if value < smallest:
smallest = value
return largest, smallest
Initializing from actual input handles negative-only data without assuming a bound such as zero. This function uses (None, None) to signal empty input; choose a different explicit policy if None could also be a valid result in your application. For a fuller explanation of iterator consumption, see Python’s Functional Programming HOWTO.
Quick Recap
Best Value
Choose the approach that fits the input
- List or other re-iterable collection: use
max()andmin()for clear, concise code. - One-pass iterator or stream: use one loop to update both extremes, or recreate the iterator if the source can be read again.
- Exercise requiring explicit comparisons: initialize from the first input and compare the remaining values, after deciding how empty input should be handled.
- Records ranked by a field: use
key=to compare that field while keeping the original record as the result.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




