In Python, if we want to get the minimum, or the maximum, or a bunch of other aggregate values we can use various built in functions like min, max, sum, any and all.
A simple use case for the minimum function is this:
>>> a_list = [ 3, 56, 1, 98, -8]
>>> min(a_list)
-8
In this example we can see that Python has compared all the values in the list and returned the lowest one.
More Complex Lists
But what if we have a list like this, and we want to find out which year Billy Joel first released an album:
billy_joel_albums = [
['Glass Houses', 1980],
['Turnstiles', 1976],
['Streetlife Serenade', 1974],
['Storm Front', 1989],
['Piano Man', 1973],
['Cold Spring Harbor', 1971],
['Fantasies & Delusions', 2001],
['The Stranger', 1977],
['The Nylon Curtain', 1982],
['The Bridge', 1986],
['An Innocent Man', 1983],
['52nd Street', 1978],
['River of Dreams', 1993],
]
Python would have no idea which of the values in the list to get the minimum of, because each of the values is a list itself.
Passing a key to the min function
That’s OK, because the min function has a parameter that allows us to identify to Python the key that we want to use. That parameter is called “key”. In this case we need to tell Python to evaluate the second element in the nested lists, being the year. We can create a function that gets that value:
>>> def get_year(item):
... return item[1]
If I pass the first item in the billy_joel_albums list to this function, it will return the year from the item:
>>> get_year(billy_joel_albums[0])
1980
Passing the get_year function to min
If I pass our get_year function to the min function, the min function will use it to get the year from each of the album lists in the main list, compare those years and pass back the album with the earliest year. We use the key parameter for this:
>>> min(billy_joel_albums,key=get_year)
['Cold Spring Harbor', 1971]
We can see that Billy Joel’s first album was Cold Spring Harbor, released in 1971.
We need to use a named argument (eg, key=get_year
) for this, because there are other parameters to the min function between the first parameter and the key parameter, and Python doesn’t know which of those parameters we want to use without us explicitly defining it as the key
parameter.
Also, notice we are passing just the name of the function (get_year), rather than executing it (get_year()). We are not executing it, Python is executing it.
Get Just the Year
The above call to the min function is returning the album list with the earliest year. If we wanted to bite off just the year in one line of code, we could add an index after the call to min:
>>> min(billy_joel_albums,key=get_year)[1]
1971
Streamlining it with a lambda function
It’s cumbersome and messy to write a whole function just to return a list item every time you want to get an aggregate value from a list of lists. There is another way we can do it in a single line, by passing a lambda, or anonymous function to the min function. The format of a lambda function is as follows:
lambda input: return
In our case we want to pass a list and return the second list item from that list (which has an index of 1):
lambda item: item[1]
Wrap it into the min function
Now we can pass the above syntax as an argument to the key parameter in the min function:
>>> min(billy_joel_albums,key=lambda item: item[1])[1]
1971
That’s a cool, quick way to get the release year of Billy Joel’s first album from an unordered list of lists!
Here’s one of the singles from that album: