profile

Rodrigo Girรฃo Serrรฃo

๐Ÿ๐Ÿ“ the parameter of max no one knows

published2 months ago
3 min read

Hey there, how are you doing?

In this issue of the Mathspp Insider we will learn about the keyword argument key of the built-in max and we will see how we can use it to find the longest word in a list of words.


The problem at hands

Last week we looked at how a beginner would solve this challenge:

Write a function get_longest that accepts a list of words and returns the longest word.

In this week's issue of the Mathspp Insider I want to share what I think is essentially the best solution you could come up with for this challenge.

A quick recap

Last week's issue ended on this solution:

def get_longest(words):
    _, longest = max((len(word), word) for word in words)
    return longest

This function might look weird, but it actually expresses a very smart idea:

โ€œFind the maximum of the words, but compare them by their length.โ€

So, our beautiful solution does this same thing, but in a better way!

Using max's optional arguments

The built-in max accepts an optional parameter called key, and the parameter key serves this exact purpose.
Instead of comparing the objects directly, you get to compare them according to a different measure.
To do this, we just need to tell max what is the function that takes an object and returns the measure we want to use.

In our case, we want to measure the words by their length, so the function that we care about is actually the built-in len.
By setting key=len, we can tell the built-in max to literally find the longest word:

def get_longest(words):
    return max(words, key=len)

This might help some of you: when you specify the key, the built-in max actually acts as the argmax.
You specify an iterable it and a function f and then max(it, key=f) will find the item in it that maximises the function f.

key and lambda

The keyword argument key of the built-in max is a good example of when one might want to use a lambda function.
In fact, many of you replied to my last email with this suggestion:

def get_longest(words):
    return max(words, key=lambda s: len(s))

What does this mean?
It means you are setting key to a function that computes the length of s by passing it to the built-in len...
But why do you need a lambda to compute the length of s, if the built-in len does that?

In the code above, lambda s: len(s) is a lambda that is a bit useless, because it just wraps the built-in len.
Instead, you can use len directly, because len is โ€œa function that computes the length of sโ€.

key in min and sorted

The parameter key isn't exclusive to the built-in max.
Naturally, the built-ins min and sorted also accept the parameter key.

In the context of word lengths, the expression min(words, key=len) will find the shortest word in words and the expression sorted(words, key=len) will sort all your words by length.

The parameter key can be set to any function you want, and obviously it does not need to be a built-in!

Another example of key

I am very active on Twitter @mathsppblog, where I post about Python daily.
Suppose I had a class that represents tweets:

class Tweet:
    def __init__(self, tweet, likes, retweets, comments):
        self.tweet = tweet
        self.likes = likes
        self.retweets = retweets
        self.comments = comments

    # ...

Now, suppose I had a list with a bunch of my tweets:

my_tweets = [
    Tweet("Did you know [...]", 113, 4, 10),
    Tweet("Is Python cool?", 43, 11, 56),
    Tweet("The built-in max [...]", 245, 33, 8),
    Tweet("I love Python.", 163, 28, 13),
]

By using the parameter key of the built-ins min, max, and sorted, I could study how my tweets performed.
For example, I could answer all of these questions:

  • What is the tweet with the most likes?
  • What is the tweet with the least comments?
  • Can you sort the tweets by number of retweets?

Now, why don't you give it a try?
Feel free to reply to this email with your solutions or with any questions you might have about the parameter key.

I look forward to getting your email!


Thanks for reading, and I'll see you next time!

Rodrigo.