Python's min() and max(): Find Smallest and Largest Values

Python's min() and max(): Find Smallest and Largest Values

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() and max() to find smallest and largest values in your data
  • Call min() and max() with a single iterable or with any number of regular arguments
  • Use min() and max() with strings and dictionaries
  • Tweak the behavior of min() and max() with the key and default arguments
  • Use comprehensions and generator expressions as arguments to min() and max()

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.

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:

Python
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.

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:

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:

Python
>>> 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:

Python
>>> 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:

Python
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:

Python
>>> 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:

Python
>>> 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.

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:

Python
>>> # 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:

Python
>>> 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:

Python
>>> 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:

Python
>>> 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: