Skip to content
Theory · Functions as values · lesson 3 of 10

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:

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

  1. sorted(words) compares the strings themselves, letter by letter, and puts them in alphabetical order.
  2. sorted(words, key=len) gets the note len and calls it for each word: 6, 3, 5, 4.
  3. The sorting follows these numbers, and the result holds the words themselves, from fig to banana.

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:

  • len is the function, the note with the rule;
  • len("fig") is the result of the call, the number 3.

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.

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

  1. check = last_letter does not call the function; it gives it a second name. The variable check refers to the same function.
  2. check("fig") is called the same way as last_letter("fig") and returns g.
  3. 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:

  1. the word lambda;
  2. the parameters before the colon;
  3. the expression after the colon—the function returns its value, without the word return.
Python
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:

Python
words = ["banana", "fig", "apple", "kiwi"]
print(sorted(words, key=len()))  # ✗
TEXT
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, min and max call the function in key for each item and compare its results.
  • lambda x: expression is 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.

Sign in another way