ZetCode

Python max Function

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.

Basic Definitions

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.

Basic Numeric Usage

Here's simple usage with different numeric types showing how max finds the largest value among numbers.

basic_max.py
# With multiple arguments
print(max(10, 20, 30))    # 30

# With an iterable
numbers = [5, 2, 8, 4, 1]
print(max(numbers))       # 8

# With mixed numeric types
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.

String Comparison

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'

# Based on Unicode values
chars = ['a', 'A', 'z', 'Z']
print(max(chars))  # 'z'

# With key function for case-insensitive comparison
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.

Custom Objects with Key Function

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"]

# Find longest word by length
longest = max(words, key=lambda x: len(x))
print(longest)  # 'elephant'

# Find word with highest ASCII sum
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.

Custom Objects with __gt__

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.

Handling Empty Iterables

The max function raises ValueError when used with empty iterables. This example shows proper error handling.

empty_iterables.py
empty_list = []

# Without default (raises error)
try:
    print(max(empty_list))
except ValueError as e:
    print(f"Error: {e}")  # max() arg is an empty sequence

# With default value
print(max(empty_list, default="No items"))  # 'No items'

# With default None
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.

Performance Considerations

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.

Best Practices

Source References

Author

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.