1. Nested Functions
You can define functions within other functions, if you want. Each new level gets its own set of local variables.
Here is a classic example:
def make_adder(x): def adder(y): return x + y return adder
What does the
make_adder function do?
Try these, and make sure you understand the results:
make_adder make_adder(3) addthree = make_adder(3) addthree(5) make_adder('sid')('ney')
Consider this function:
def t(f): def g(x): return f(f(f(x))) return g
Ask yourself: What does
t do? What does
Figure out the answer before you try it yourself.
2. Functions as first-class objects
make_adder example above, we demonstrated a function that returned a function. The
t function took in a function as an argument and returned another function! This demonstrates two of the features of a language that treats functions as first-class objects; they can be passed in to functions and returned from functions. This was a fundamental breakthrough in programming languages when it was introduced years ago; before that data was data and functions were functions and never the twain shall meet. That Python supports this feature allows us to do very powerful things, which we'll see later in the course.
3. Lambda forms
You can return a function without needing to write a nested function -- there's a Python "shorthand" that allows you to write small anonymous functions, and it's called
lambda. Here is a small example:
plus = lambda x,y: x + y
which would define
plus to be the function which takes two arguments (
y) and returns the value of the expression
x + y. This has the same result as if we had defined it the standard way:
def plus(x,y): return x + y
There are a few reasons the
lambda form is so useful, which will become apparent as you work with higher-order functions later on (functions that take other functions as input). The first is that if you need to pass in a function as an argument to another function, it's a pain to use a
def and have to come up with a name which will only be used once.
Lambda lets you pass in the function directly with fewer keystrokes. The second occurs when you are returning a function -- it saves from having to define and return a nested function. Consider the definition of
t. Look how simple it becomes when we use a
def t(f): return lambda x: f(f(f(x)))
There are other reasons to use a
lambda, and the more you use it, the more you'll realize how handy it is.
If all of this seems completely foreign or overwhelming to you after you've experimented with it a bit, come on in to the Self-Paced Center and speak with a tutor.