Complete guide to Python's max function covering numbers, strings, custom objects, and practical examples of finding maximum values.
Last modified April 11, 2025
This comprehensive guide explores Python’s max function, which returns the largest item in an iterable or among arguments. We’ll cover numbers, strings, custom objects, and practical examples.
The max function returns the largest item from an iterable or two or more arguments. It can accept a key function for custom comparisons and a default value for empty iterables.
Key characteristics: works with any comparable types (numbers, strings, etc.), accepts optional key function, and raises ValueError for empty iterables without default.
Here’s simple usage with different numeric types showing how max finds the largest value among numbers.
basic_max.py
print(max(10, 20, 30)) # 30
numbers = [5, 2, 8, 4, 1] print(max(numbers)) # 8
print(max(3.14, 2, 5.6)) # 5.6
This example shows max with different numeric inputs. It works with both separate arguments and iterables. Python automatically handles mixed numeric types.
The function compares values using standard comparison rules, so integers and floats can be compared directly.
The max function can also compare strings, finding the lexicographically largest string based on Unicode code points.
string_max.py
words = [“apple”, “banana”, “cherry”] print(max(words)) # ‘cherry’
chars = [‘a’, ‘A’, ‘z’, ‘Z’] print(max(chars)) # ‘z’
print(max(words, key=lambda x: x.lower())) # ‘cherry’
String comparison is case-sensitive by default, with uppercase letters having lower Unicode values than lowercase. The key function allows custom comparison logic.
The example shows how to perform case-insensitive comparison by converting strings to lowercase during comparison.
The key function parameter enables finding maximum values based on custom criteria. This example finds the longest word in a list.
key_function.py
words = [“cat”, “elephant”, “mouse”, “giraffe”]
longest = max(words, key=lambda x: len(x)) print(longest) # ’elephant’
max_ascii = max(words, key=lambda x: sum(ord(c) for c in x)) print(max_ascii) # ’elephant’
The first example finds the longest word using len as the key. The second calculates the sum of ASCII values for each character in the word.
Key functions allow flexible comparisons without modifying the original data or creating custom comparison methods.
You can make custom objects work with max by implementing the gt special method. This example creates a Person class.
custom_max.py
class Person: def init(self, name, age): self.name = name self.age = age
def __gt__(self, other):
return self.age > other.age
def __repr__(self):
return f"Person('{self.name}', {self.age})"
people = [ Person(“Alice”, 25), Person(“Bob”, 30), Person(“Charlie”, 20) ]
print(max(people)) # Person(‘Bob’, 30)
The Person class implements gt to compare by age. When we call max on a list of Person instances, Python uses this method.
This pattern is useful when you want objects to have a natural ordering for comparison operations.
The max function raises ValueError when used with empty iterables. This example shows proper error handling.
empty_iterables.py
empty_list = []
try: print(max(empty_list)) except ValueError as e: print(f"Error: {e}") # max() arg is an empty sequence
print(max(empty_list, default=“No items”)) # ‘No items’
print(max(empty_list, default=None)) # None
These examples demonstrate max’s behavior with empty sequences. Providing a default value prevents the ValueError for empty iterables.
The default parameter is particularly useful when working with data that might be empty, such as database query results.
This example compares max performance with alternative methods for finding maximum values.
performance.py
import timeit import random
numbers = [random.randint(1, 1000) for _ in range(10000)]
def test_max(): return max(numbers)
def test_sorted(): return sorted(numbers)[-1]
def test_loop(): m = numbers[0] for n in numbers[1:]: if n > m: m = n return m
print(“max():”, timeit.timeit(test_max, number=1000)) print(“sorted():”, timeit.timeit(test_sorted, number=1000)) print(“Loop:”, timeit.timeit(test_loop, number=1000))
This benchmarks different maximum-finding methods. max is generally fastest as it’s optimized for this specific operation.
The sorted approach is much slower as it sorts the entire list. The manual loop is closer but less readable than max.
Use for readability: Prefer max over manual loops
Implement gt: For custom types that need natural ordering
Use key functions: For complex comparison criteria
Handle empty cases: Use default parameter with uncertain data
Document behavior: Clearly document comparison logic
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all Python tutorials.