CS61A Day1 lambda 递归
lambda 匿名函数
lambda的形式如下
lambda [arg1 [,arg2,.....argn]]:expression
可以发现,lambda就是以arg1直到argn(如果有那么多变量的话),返回expression,expression是该匿名函数的函数体和返回值.比如
act = lambda x: x + 1
act(3)
就是将这个匿名函数赋值给act, act(3) = 3 + 1 = 4.
对于嵌套的lambda ,如
action = lambda x: lambda y: x + y
act = action(99)
act(3)
这个就相当于下面的def形式
def action(x):
return lambda y: x + y
act = action(99)
act(3)
而如果想要直接调用action来计算,则需要写成action(99)(3)的形式
再举一通过匿名函数实现递归阶乘例
def make_anonymous_factorial():
"""Return the value of an expression that computes factorial.
>>> make_anonymous_factorial()(5)
120
>>> from construct_check import check
>>> check(HW_SOURCE_FILE, 'make_anonymous_factorial', ['Assign', 'AugAssign', 'FunctionDef', 'Recursion'])
True
"""
return (lambda f: lambda x: f(f, x))(lambda f, x: x if x == 1 else x * f(f, x-1))
返回值中,(lambda f, x: x if x == 1 else x * f(f, x-1))是前一部分的嵌套匿名函数(lambda f: lambda x: f(f, x))中的参数f,所以调用make_anonymous_factor( )时后面只需要输入参数x
Higher Order Functions 高阶函数
首先,需要知道在python中函数名同样是一个变量.比如add( ),其返回值是将各参数之和,而如果有
>>> func = add
则可以像调用add(x, y)一样调用func(x, y).
同样的,函数名也可以作为传入函数的参数和返回值
>>> def trace1(fn):
def wrapped(x):
print('-> ', fn, '(', x, ')')
return fn(x)
return wrapped
>>> @trace1
def triple(x):
return 3 * x
>>> triple(12)
-> <function triple at 0x102a39848> ( 12 )
36
trace1( )是一个高阶函数, 返回值是wrapped( ), 假如有
>>> func = trace1()
那么会先执行trace1( ) 中return前的code, 并有func = wrapped, func(x) = wrapped(x)
对于triple(x), 其不仅是一个def, 并且有一个注释, 调用triple相当于
triple = trace1(triple)
另外,如果是一个多层嵌套的高阶函数,如果内层的函数试图引用外层的函数定义和声明的变量n, 在不修改n的值的情况下可以直接调用
如果内层函数需要对n进行修改,则需要在内层函数里有以下声明
nonlocal n
如下例:
def make_adder_inc(n):
"""
>>> adder1 = make_adder_inc(5)
>>> adder2 = make_adder_inc(6)
>>> adder1(2)
7
>>> adder1(2) # 5 + 2 + 1
8
>>> adder1(10) # 5 + 10 + 2
17
>>> [adder1(x) for x in [1, 2, 3]]
[9, 11, 13]
>>> adder2(5)
11
"""
"*** YOUR CODE HERE ***"
m = -1
def func(x):
nonlocal m
m += 1
return n + x + m
return func
参考资料
- 廖雪峰的python教程函数式编程部分
https://www.liaoxuefeng.com/wiki/1016959663602400/1017328525009056 - SICP python描述 1.6高阶函数
https://wizardforcel.gitbooks.io/sicp-py/content/1.6.html - Python学习手册(第四版) p483-488
- CS61A lab 02
https://inst.eecs.berkeley.edu/~cs61a/su19/lab/lab02/
CS61A Day1 lambda 递归
http://zqizhang.github.io/2022/01/13/CS61A-Day1/