Lab 5 Solutions
Lambda
Lambda
expressions are oneline functions that specify two things:
the parameters and the return value.
lambda <parameters>: <return value>
While both lambda
and def
statements are related to functions, there are some differences.
lambda  def  

Type  lambda is an expression 
def is a statement 
Description  Evaluating a lambda expression does not create or modify any variables.
Lambda expressions just create new function objects. 
Executing a def statement will create a new function object and bind it to a variable in the current environment. 
Example 


A lambda
expression by itself is not very interesting. As with any objects such as numbers, booleans, strings, we usually:
 assign lambda to variables (
foo = lambda x: x
)  pass them in to other functions (
bar(lambda x: x)
)  return them as the results of other functions (
return lambda x: x
)  return them as the results of other lambdas (
lambda x: lambda y: x + y
)
In the final example above, the outer lambda (lambda x
) takes in a value x
, and it
returns another lambda (lambda y
) that takes an argument y
and returns x+y
.
Environment Diagrams
Environment diagrams are one of the best learning tools for understanding
lambda
expressions because you're able to keep
track of all the different names, function objects, and arguments to functions.
We highly recommend drawing environment diagrams or using Python
tutor if you get stuck doing the WWPD problems below.
For examples of what environment diagrams should look like, try running some
code in Python tutor. Here are the rules:
Lambdas
Note: As we saw in the
lambda
expression section above,lambda
functions have no intrinsic name. When drawinglambda
functions in environment diagrams, they are labeled with the namelambda
or with the lowercase Greek letter λ. This can get confusing when there are multiple lambda functions in an environment diagram, so you can distinguish them by numbering them or by writing the line number on which they were defined.
 Draw the lambda function object and label it with λ, its formal parameters, and its parent frame. A function's parent frame is the frame in which the function was defined.
This is the only step. We are including this section to emphasize the fact that
the difference between lambda
expressions and def
statements is that
lambda
expressions do not create any new bindings in the environment.
WWPD
Question 1: WWPD: Lambda the Free
Use Ok to test your knowledge with the following "What Would Python Display?" questions:
python3 ok q lambda u
For all WWPD questions, type
Function
if you believe the answer is<function...>
,Error
if it errors, andNothing
if nothing is displayed. As a reminder, the following two lines of code will not display anything in the Python interpreter when executed:>>> x = None >>> x
>>> lambda x: x # A lambda expression with one parameter x
______<function <lambda> at ...>
>>> a = lambda x: x # Assigning the lambda function to the name a
>>> a(5)
______5
>>> (lambda: 3)() # Using a lambda expression as an operator in a call exp.
______3
>>> b = lambda x: lambda: x # Lambdas can return other lambdas!
>>> c = b(88)
>>> c
______<function <lambda> at ...
>>> c()
______88
>>> d = lambda f: f(4) # They can have functions as arguments as well.
>>> def square(x):
... return x * x
>>> d(square)
______16
>>> z = 3
>>> e = lambda x: lambda y: lambda: x + y + z
>>> e(0)(1)()
______4
>>> f = lambda z: x + z
>>> f(3)
______NameError: name 'x' is not defined
>>> higher_order_lambda = lambda f: lambda x: f(x)
>>> g = lambda x: x * x
>>> higher_order_lambda(2)(g) # Which argument belongs to which function call?
______Error
>>> higher_order_lambda(g)(2)
______4
>>> call_thrice = lambda f: lambda x: f(f(f(x)))
>>> call_thrice(lambda y: y + 1)(0)
______3
>>> print_lambda = lambda z: print(z) # When is the return expression of a lambda expression executed?
>>> print_lambda
______Function
>>> one_thousand = print_lambda(1000)
______1000
>>> one_thousand
______# print_lambda returned None, so nothing gets displayed
Question 2: WWPD: Higher Order Functions
Use Ok to test your knowledge with the following "What Would Python Display?" questions:
python3 ok q hof u
For all WWPD questions, type
Function
if you believe the answer is<function...>
,Error
if it errors, andNothing
if nothing is displayed.
>>> def even(f):
... def odd(x):
... if x < 0:
... return f(x)
... return f(x)
... return odd
>>> steven = lambda x: x
>>> stewart = even(steven)
>>> stewart
______<function ...>
>>> stewart(61)
______61
>>> stewart(4)
______4
>>> def cake():
... print('beets')
... def pie():
... print('sweets')
... return 'cake'
... return pie
>>> chocolate = cake()
______beets
>>> chocolate
______Function
>>> chocolate()
______sweets
'cake'
>>> more_chocolate, more_cake = chocolate(), cake
______sweets
>>> more_chocolate
______'cake'
>>> def snake(x, y):
... if cake == more_cake:
... return lambda: x + y
... else:
... return x + y
>>> snake(10, 20)
______Function
>>> snake(10, 20)()
______30
>>> cake = 'cake'
>>> snake(10, 20)
______30
Environment Diagram Practice
There is no submission for this component. However, we still encourage you to do these problems on paper to develop familiarity with Environment Diagrams, which will appear on the exam.
Question 3: Make Adder
Draw the environment diagram for the following code:
n = 9
def make_adder(n):
return lambda k: k + n
add_ten = make_adder(n+1)
result = add_ten(n)
There are 3 frames total (including the Global frame). In addition, consider the following questions:
 In the Global frame, the name
add_ten
points to a function object. What is the intrinsic name of that function object, and what frame is its parent?  In frame
f2
, what name is the frame labeled with (add_ten
or λ)? Which frame is the parent off2
?  What value is the variable
result
bound to in the Global frame?
You can try out the environment diagram at tutor.cs61a.org. To see the environment diagram for this question, click here.
 The intrinsic name of the function object that
add_ten
points to is λ (specifically, the lambda whose parameter isk
). The parent frame of this lambda isf1
. f2
is labeled with the name λ the parent frame off2
isf1
, since that is where λ is defined. The variable
result
is bound to 19.
Question 4: Lambda the Environment Diagram
Try drawing an environment diagram for the following code and predict what Python will output.
You do not need to submit or unlock this question through Ok. Instead, you can check your work with the Online Python Tutor, but try drawing it yourself first!
>>> a = lambda x: x * 2 + 1
>>> def b(b, x):
... return b(x + a(x))
>>> x = 3
>>> b(a, x)
______21 # Interactive solution: https://goo.gl/Lu99QR
Lambda
Question 5: Compose
Write a function that takes in 2 singleargument functions, f and g, and returns another lambda function that takes in a single argument x. The returned function should return the output of applying f(g(x)).
Hint: The staff solution is only 1 line!
def compose(f, g):
"""Write a function that takes in 2 singleargument functions, f and g, and returns another lambda function
that takes in a single argument x. The returned function should return the output of applying f(g(x)).
Hint: The staff solution is only 1 line!
Return the composition function which given x, computes f(g(x)).
>>> add_two = lambda x: x + 2 # adds 2 to x
>>> square = lambda x: x ** 2 # squares x
>>> a = compose(square, add_two) # (x + 2 ) ^ 2
>>> a(5)
49
>>> mul_ten = lambda x: x * 10 # multiplies 10 with x
>>> b = compose(mul_ten, a) # ((x + 2 ) ^ 2) * 10
>>> b(5)
490
>>> b(2)
160
"""
"*** YOUR CODE HERE ***"
return lambda x: f(g(x))
Use OK to test your code:
python3 ok q compose
Question 6: Mul_by_num
Using a lambda
expression, complete the mul_by_num
function. This
function should take an argument and return a one argument function
that multiplies any value passed to it by the original number. Its
body must be one line long:
def mul_by_num(num):
"""
Returns a function that takes one argument and returns num
times that argument.
>>> x = mul_by_num(5)
>>> y = mul_by_num(2)
>>> x(3)
15
>>> y(4)
8
"""
"*** YOUR CODE HERE ***"
return lambda num2: num * num2
Higher Order Functions
Question 7: Funception
Write a function (funception) that takes in another function func_a
and a number start
and returns a function (func_b
) that will have one parameter to take in the stop value.
func_b
should take the following into consideration the following in order:
 Takes in the stop value.
 If the value of
start
is less than 0, it should exit the function.  If the value of
start
is greater than stop, applyfunc_a
onstart
and return the result.  If not, apply
func_a
on all the numbers from start (inclusive) up to stop (exclusive) and return the product.
def funception(func_a, start):
""" Takes in a function (function A) and a start value.
Returns a function (function B) that will find the product of
function A applied to the range of numbers from
start (inclusive) to stop (exclusive)
>>> def func_a(num):
... return num + 1
>>> func_b1 = funception(func_a, 3)
>>> func_b1(2)
4
>>> func_b2 = funception(func_a, 2)
>>> func_b2(3)
>>> func_b3 = funception(func_a, 1)
>>> func_b3(4)
>>> func_b4 = funception(func_a, 0)
>>> func_b4(3)
6
>>> func_b5 = funception(func_a, 1)
>>> func_b5(4)
24
"""
"*** YOUR CODE HERE ***"
def func_b(stop):
i = start
product = 1
if start < 0:
return None
if start > stop:
return func_a(start)
while i < stop:
product *= func_a(i)
i += 1
return product
return func_b
Use OK to test your code:
python3 ok q funception