Higher-order functions and lambdas

INPUT · Slides

A function is a value

01 / 07

A function was something you called

When you met def back in chapter 3, a function was something you called. You wrote double(5) and got an answer. That was the whole of it.

This chapter turns that round. A function is a value. It goes into a variable exactly as a number or a string does.

Look at f = double below. There are no parentheses after double. That alone makes f the same function as double.

def double(x):    return x * 2f = doubleprint(f(5))

Result

10

02 / 07

The parentheses change the meaning

This is the most important thing in the chapter.

  • double(5) … the result of calling the function. The number 10
  • double … the function itself. The lump of work called "double it"

Parentheses are the signal to use it. Leave them off and you get the work itself, as a value.

Incidentally, print a function itself and you see something like this.

<function double at 0x7f3c2a1b4040>

The number on the end is where it is kept, and it changes every time you run. Not much to look at, but it does show that the function genuinely exists as a value.

def double(x):    return x * 2f = doubleprint(double(5))print(f(5))

Result

10
10

03 / 07

Making a function with no name

If a function is a value, then you ought to be able to make one on the spot without naming it — the same way you can write 5 or "red" without putting either into a variable first.

The way to write that is lambda. The shape is this.

lambda arguments: expression

After lambda comes the name of the argument, then a colon, then one expression. That is a small function, complete.

double = lambda x: x * 2print(double(5))

Result

10

04 / 07

Side by side with def

Put the two versions of the same work next to each other.

def double(x):    return x * 2
double = lambda x: x * 2

Three lines with def, one with lambda. The parts line up.

  • the (x) of def double(x): is the x of lambda x:
  • the x * 2 of return x * 2 is the x * 2 after the colon

You call them in exactly the same way as well. Either one is double(5).

def double(x):    return x * 2double2 = lambda x: x * 2print(double(7))print(double2(7))

Result

14
14

05 / 07

You do not write return

You may have spotted it in the comparison: there is no return in a lambda.

It is not that you leave it out — you cannot put it in. All that can follow a lambda is a single expression, and the answer to that expression is the return value.

Write return by mistake and you get the error below.

double = lambda x: return x * 2

Result

SyntaxError: invalid syntax

06 / 07

Anything that is an expression will go in

So long as it is an expression, the contents are up to you. Two arguments or more is fine.

a if condition else b, from chapter 9, was an expression and not a statement. That is why it can sit inside a lambda, and why a small function that switches on a condition fits on one line.

add = lambda a, b: a + bgrade = lambda s: "pass" if s >= 60 else "fail"print(add(2, 3))print(grade(80))

Result

5
pass

07 / 07

If you are naming it, use def

We have been writing double = lambda x: x * 2, and the truth is that goes against the grain of Python.

If you are giving it a name and keeping it, write it plainly with def. The reasons are clear: def reads better, and the name shows up when something goes wrong. A function made with lambda appears in the error as nothing but <lambda>, so you cannot tell which one you tripped over.

So when is lambda right? When you hand it over on the spot and never use it again. Work too small to be worth a name, needed once.

The next lesson is exactly that situation: telling sorted what to sort by.