Watch Now This tutorial has a related video course created by the Real Python team. Watch it together with the written tutorial to deepen your understanding: Using Python's min() and max()
Python’s built-in min() and max() functions come in handy when you need to find the smallest and largest values in an iterable or in a series of regular arguments. Even though these might seem like fairly basic computations, they turn out to have many interesting use cases in real-world programing. You’ll try out some of those use cases here.
In this tutorial, you’ll learn how to:
- Use Python’s
min()andmax()to find smallest and largest values in your data - Call
min()andmax()with a single iterable or with any number of regular arguments - Use
min()andmax()with strings and dictionaries - Tweak the behavior of
min()andmax()with thekeyanddefaultarguments - Use comprehensions and generator expressions as arguments to
min()andmax()
Once you have this knowledge under your belt, then you’ll be prepared to write a bunch of practical examples that will showcase the usefulness of min() and max(). Finally, you’ll code your own versions of min() and max() in pure Python, which can help you understand how these functions work internally.
Free Bonus: 5 Thoughts On Python Mastery, a free course for Python developers that shows you the roadmap and the mindset you’ll need to take your Python skills to the next level.
To get the most out of this tutorial, you should have some previous knowledge of Python programming, including topics like for loops, functions, list comprehensions, and generator expressions.
Getting Started With Python’s min() and max() Functions
Python includes several built-in functions that make your life more pleasant and productive because they mean you don’t need to reinvent the wheel. Two examples of these functions are min() and max(). They mostly apply to iterables, but you can use them with multiple regular arguments as well. What’s their job? They take care of finding the smallest and largest values in their input data.
Whether you’re using Python’s min() or max(), you can use the function to achieve two slightly different behaviors. The standard behavior for each is to return the minimum or maximum value through straightforward comparison of the input data as it stands. The alternative behavior is to use a single-argument function to modify the comparison criteria before finding the smallest and largest values.
To explore the standard behavior of min() and max(), you can start by calling each function with either a single iterable as an argument or with two or more regular arguments. That’s what you’ll do right away.
Calling min() and max() With a Single Iterable Argument
The built-in min() and max() have two different signatures that allow you to call them either with an iterable as their first argument or with two or more regular arguments. The signature that accepts a single iterable argument looks something like this:
min(iterable, *[, default, key]) -> minimum_value
max(iterable, *[, default, key]) -> maximum_value
Both functions take a required argument called iterable and return the minimum and maximum values respectively. They also take two optional keyword-only arguments: default and key.
Note: In the above signatures, the asterisk (*) means that the following arguments are keyword-only arguments, while the square brackets ([]) denote that the enclosed content is optional.
Here’s a summary of what the arguments to min() and max() do:
| Argument | Description | Required |
|---|---|---|
iterable |
Takes an iterable object, like a list, tuple, dictionary, or string | Yes |
default |
Holds a value to return if the input iterable is empty | No |
key |
Accepts a single-argument function to customize the comparison criteria | No |
Later in this tutorial, you’ll learn more about the optional default and key arguments. For now, just focus on the iterable argument, which is a required argument that leverages the standard behavior of min() and max() in Python:
>>> min([3, 5, 9, 1, -5])
-5
>>> min([])
Traceback (most recent call last):
...
ValueError: min() arg is an empty sequence
>>> max([3, 5, 9, 1, -5])
9
>>> max([])
Traceback (most recent call last):
...
ValueError: max() arg is an empty sequence
In these examples, you call min() and max() with a list of integer numbers and then with an empty list. The first call to min() returns the smallest number in the input list, -5. In contrast, the first call to max() returns the largest number in the list, or 9. If you pass an empty iterator to min() or max(), then you get a ValueError because there’s nothing to do on an empty iterable.
An important detail to note about min() and max() is that all the values in the input iterable must be comparable. Otherwise, you get an error. For example, numeric values work okay:
>>> min([3, 5.0, 9, 1.0, -5])
-5
>>> max([3, 5.0, 9, 1.0, -5])
9
These examples combine int and float numbers in the calls to min() and max(). You get the expected result in both cases because these data types are comparable.
However, what would happen if you mixed strings and numbers? Check out the following examples:
>>> min([3, "5.0", 9, 1.0, "-5"])
Traceback (most recent call last):
...
TypeError: '<' not supported between instances of 'str' and 'int'
>>> max([3, "5.0", 9, 1.0, "-5"])
Traceback (most recent call last):
...
TypeError: '>' not supported between instances of 'str' and 'int'
You can’t call min() or max() with an iterable of noncomparable types as an argument. In this example, a function tries to compare a number to a string, which is like comparing apples and oranges. The end result it that you get a TypeError.
Calling min() and max() With Multiple Arguments
The second signature of min() and max() allows you to call them with any number of arguments, provided that you use at least two arguments. This signature has the following form:
min(arg_1, arg_2[, ..., arg_n], *[, key]) -> minimum_value
max(arg_1, arg_2[, ..., arg_n], *[, key]) -> maximum_value
Again, these functions return the minimum and maximum values, respectively. Here’s the meaning of the arguments in the above signature:
| Argument | Description | Required |
|---|---|---|
arg_1, arg_2, ..., arg_n |
Accepts any number of regular arguments to compare | Yes (at least two of them) |
key |
Takes a single-argument function to customize the comparison criteria | No |
This variation of min() or max() doesn’t have a default argument. You must provide at least two arguments in the call for the function to work correctly. So, a default value isn’t required, because you’ll always have at least two values to compare in order to find the minimum or maximum.
To try out this alternative signature, run the following examples:
>>> min(3, 5, 9, 1, -5)
-5
>>> max(3, 5, 9, 1, -5)
9
You can call min() or max() with two or more regular arguments. Again, you’ll get the minimum or maximum value in the input data, respectively. The only condition is that the arguments must be comparable.
Using min() and max() With Strings and Iterables of Strings
By default, min() and max() can process values that are comparable. Otherwise, you get a TypeError, as you’ve already learned. Up to this point, you’ve seen examples that use numeric values either in an iterable or as multiple regular arguments.
Using min() and max() with numeric values is arguably the most common and useful use case of these functions. However, you can also use the functions with strings and iterables of strings. In these cases, the alphabetical order of characters will decide the final result.
For example, you can use min() and max() to find the smallest and largest letters in some text. In this context, smallest means closest to the beginning of the alphabet, and largest means closest to the end of the alphabet:
>>> min("abcdefghijklmnopqrstuvwxyz")
'a'
>>> max("abcdefghijklmnopqrstuvwxyz")
'z'
>>> min("abcdWXYZ")
'W'
>>> max("abcdWXYZ")
'd'
As promised, in the first two examples, min() returns 'a' and max() returns 'z'. However, in the second pair of examples, min() returns 'W' and max() returns 'd'. Why? Because uppercase letters come before lowercase letters in Python’s default character set, UTF-8.
Note: Python internally treats strings as iterables of characters. So, calling min() or max() with a string as an argument is like calling the function with an iterable of individual characters.
Using min() or max() with a string as an argument isn’t limited to just letters. You can use strings containing any possible characters in your current character set. For example, if you’re working with the set of ASCII characters only, then the smallest character is the character closest to the beginning of the ASCII table. In contrast, the largest character is the character closest to the end of the table.
With other character sets like UTF-8, min() and max() behave similarly:
>>> # UTF-8 characters
>>> min("abc123ñ")
'1'
>>> max("abc123ñ")
'ñ'
Behind the scenes, min() and max() use the character’s numeric value to find the minimum and maximum characters in the input string. For example, in the Unicode character table, the uppercase A has a smaller numeric value than the lowercase a:
>>> ord("A")
65
>>> ord("a")
97
Python’s built-in ord() function takes a single Unicode character and returns an integer representing the Unicode code point of that character. In these examples, the code point for the uppercase "A" is lower than the code point for the lowercase "a".
This way, when you call min() and max() with both letters, you get results that match the order of the underlying Unicode code points of these letters:
>>> min("aA")
'A'
>>> max("aA")
'a'
What makes "A" smaller than "a"? The quick answer is the letter’s Unicode code point. All characters that you can type on your keyboard, and many other characters, have their own code points in the Unicode table. Python uses these code points to determine the minimum and maximum character when it comes to using min() and max().
Finally, you can also call min() and max() with iterables of strings or with multiple string arguments. Again, both functions will determine their return value by comparing the strings alphabetically:
>>> min(["Hello", "Pythonista", "and", "welcome", "world"])
'Hello'
>>> max(["Hello", "Pythonista", "and", "welcome", "world"])
'world'
To find the smallest or largest string in an iterable of strings, min() and max() compare all the strings alphabetically based on the code points of initial characters.
In the first example, the uppercase "H" comes before "P", "a", and "w" in the Unicode table. So, min() immediately concludes that "Hello" is the smallest string. In the second example, the lowercase "w" comes after all the other strings’ initial letters.
Note that there are two words that start with "w", "welcome" and "world". So, Python proceeds to look at the second letter of each word. The result is that max() returns "world" because "o" comes after "e".
Processing Dictionaries With min() and max()
When it comes to processing Python dictionaries with min() and max(), you need to consider that if you use the dictionary directly, then both functions will operate on the keys: