How I teach Python's Anonymous functions
Posted on March 1, 2018A lot of people switching to Python tells me that they don't understand lambda or anonymous functions. For the purpose of teaching programming beginners this, I make sure that they first understand the following fundamentals:
- data types
- lists
- list.sort()
- functions
# The fundamentals of anonymous functions
## Data types
While its basic, I need to check that my students have at least a basic knowledge on this. This is what I cover before the first hour of class is over.
## Lists data type
Whether the students know of data type from previous programming languages or not, I'll introduce lists as a new data type. This is to give them expectation later that I'm going to introduce more data types (spoilers, I will).
I introduce lists as a data type container that can contain any data types, such as string and integers.
## List.sort()
I do a simple program that sorts fruits (or superheroes if I sense that someone haven't eaten yet).
fruits = ["Banana", "Apple", "Durian", "Carrot"]
fruits.sort()
for fruit in fruits:
print("I love {}".format(fruit))
While this code is straightforward, it sets the foundation for anonymous functions. The simplicity gives the student confidence that I can tap into later.
## Functions
Again, a simple example will be introduced to carry the sense that code can be logical.
def greet(name):
print("Hello {}".format(name))
# The setup
I don't want to unintentionally scare my student of anonymous functions. And if there are some people who encountered them before the class, I don't want their preconceptions to block their mind. So I don't announce that I'm going to teach lambdas; I just do them.
First, I go back to the previous list example and add some numbers.
fruits = [["Banana", 4],
["Apple", 3],
["Durian", 1],
["Carrot", 2]]
print(fruits[2])
print(fruits[2][1])
ranking = fruits[3]
print(ranking[0])
print(ranking[1])
This is when I reveal what I said earlier about lists: they contain any data types and that includes lists. I let them absorb this idea before I go to the next question: how do you sort by rank, or put another way, by the second element of a list?
fruits.sort()
for fruit in fruits:
print("I love {}".format(fruit))
Running this code outputs Apple, Banana, Carrot, and Durian in that order. I tell the group that this isn't what we want - we want to rank by number, not by the first element. So I'll create a function and send that as the parameter:
def get_rank(fruit):
return fruit[1]
fruits.sort(key=get_rank)
There will be some confusion here. Which is good. Confusion while learning is the brain's way of telling you that you need to pay attention so it can absorb the revelation.
(Bananas are deadly)
# The plot twist
After a minute of confusion, I'll go back to the previous example for functions. This when I assign any functions into a variable:
def greet(name):
print("Hello {}".format(name))
say_hi = greet
say_hi("Mr Thompson")
I then reveal that functions.... are data types! And as a data type, you can assign functions to a variable.
I will go deeper and remind them that parameters can be any data type, so you can have a function call a function that was passed as a parameter. Something like this:
def greet_morning():
print("Good morning")
def greet_evening():
print("Good evening")
def acknowledge(func):
func()
acknowledge(greet_morning)
acknowledge(greet_evening)
# Absorbing the knowledge
At this point, a majority of my student's face will light up with understanding. For the minority, I let them think about it for a while and give more examples. This is also one of the turning point in the class where people coming from static programming languages accepts the idea of dynamic type systems.
I then go back to the sort key function and let the students digest the implication of function data types.
I'll be expecting a lot of questions here and I try my best to answer them.
# A wild lambda appears
Once the class understand (or stay confused; which is a good thing since they can go back later and maybe get an aha moment once their brain process the confusion), I introduce the lambda.
fruits = [["Banana", 4],
["Apple", 3],
["Durian", 1],
["Carrot", 2]]
def get_rank(fruit):
return fruit[1]
# fruits.sort(key=get_rank)
fruits.sort(key=lambda fruit:fruit[1])
I tell them that this is an anonymous function - or a function without a name. I point out with hand gestures how the lambda is basically the same as get_rank with its parameter and return values.
I tell them that a lambda is basically a way for making simple functions to pass as arguments (I know there are other use for lambdas, but I focus on simplicity to minimize hurting themselves in confusion).
By using an anonymous function, they can increase code readability.
# The lambda's final form
Again, there will be confusion but the class have to move on. As a parting gift, I need to show how lambdas are traditionally used in the wild. I need to do this now while the iron brain is hot.
I tell them, that it is tradition to use one letter variables for the parameter. This is to minimize the time it takes to name a variable and further increase readability.
# fruits.sort(key=lambda fruit:fruit[1])
fruits.sort(key=lambda x:x[1])
And that is how I teach anonymous functions. We take a break to let the confusion subside.
