Functions as values
Picture handing a helper a stack of word cards and asking them to put the cards in order. The helper knows how to sort but not by which rule. So you give them a note: "compare the words by length". In Python, that note is a function you pass to another function.
The sorted function puts strings in alphabetical order. To sort words by length, it must be told what to compare. For this, sorted is given another function, in the keyword argument key:
words = ["banana", "fig", "apple", "kiwi"]
print(sorted(words)) # ['apple', 'banana', 'fig', 'kiwi']
print(sorted(words, key=len)) # ['fig', 'kiwi', 'apple', 'banana']Let's walk through the example line by line:
sorted(words)compares the strings themselves, letter by letter, and puts them in alphabetical order.sorted(words, key=len)gets the notelenand calls it for each word:6,3,5,4.- The sorting follows these numbers, and the result holds the words themselves, from
figtobanana.
As you already know, key works the same way in min and max.
A function is a value
A function's name without parentheses is the function itself, and with parentheses it is a call:
lenis the function, the note with the rule;len("fig")is the result of the call, the number3.
A function, like a number or a string, can be assigned to a variable or passed as an argument. With the key argument, sorted calls len once for each word and compares the results, not the words themselves.
You can pass your own function too. A function that takes another function or returns one is called a higher-order function: sorted with key is one of them.
def last_letter(word):
return word[-1]
words = ["banana", "fig", "apple", "kiwi"]
check = last_letter
print(check("fig")) # g
print(sorted(words, key=last_letter)) # ['banana', 'apple', 'fig', 'kiwi']Let's go step by step:
check = last_letterdoes not call the function; it gives it a second name. The variablecheckrefers to the same function.check("fig")is called the same way aslast_letter("fig")and returnsg.sorted(words, key=last_letter)sorts the words by their last letter:a,e,g,i.
This is where the note picture stops working. A note is read once, but sorted calls the function again for each item. Each time, the function gets one item and returns its key.
lambda
Writing a separate def for a single key takes a while. A lambda is a function without a name, written as one expression: lambda word: word[-1] does the same as last_letter. It has three parts:
- the word
lambda; - the parameters before the colon;
- the expression after the colon—the function returns its value, without the word
return.
scores = [("max", 3), ("lee", 5), ("kim", 3)]
by_score = sorted(scores, key=lambda s: s[1])
print(by_score) # [('max', 3), ('kim', 3), ('lee', 5)]The key here is the second item of the tuple, the score. max and kim have equal keys, and sorted kept the original order: max was earlier, although kim comes first alphabetically.
Sorting in Python is stable: items with equal keys keep the order they were in. The sort method with a key argument sorts the same way. Interviewers often ask whether sorting is stable, usually with an example like this one.
map and filter
The built-in map and filter also take a function as their first argument. Like a generator expression, they produce values one at a time, so their result is wrapped in list.
map
map calls the function for each item and produces its results. list(map(len, words)) gives [6, 3, 5, 4], the length of each word.
filter
filter keeps the items for which the function returned a truthy value. list(filter(lambda w: len(w) > 4, words)) gives ['banana', 'apple'].
A comprehension is usually written instead of both, because it reads more easily. [len(w) for w in words] and [w for w in words if len(w) > 4] give the same results.
Common mistake
A function call was passed to key instead of the function itself:
words = ["banana", "fig", "apple", "kiwi"]
print(sorted(words, key=len())) # ✗TypeError: len() takes exactly one argument (0 given)The parentheses call len right away, before sorting, and with no argument. Even with an argument, key would get a number, not a function. Write the name without parentheses: key=len.
Key points
- A function's name without parentheses is the function itself: you can assign it to a variable or pass it as an argument.
sorted,minandmaxcall the function inkeyfor each item and compare its results.lambda x: expressionis a short function without a name that returns the expression's value.- Sorting is stable: items with equal keys keep their original order.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.