匿名函数 lambda
匿名函数的命名规则,用 lamdba 关键字标识,冒号 :
左侧表示函数接收的参数(a,b) , 冒号 :
右侧表示函数的返回值(a+b)。
因为 lamdba 在创建时不需要命名,不需要显式地指定函数 ,所以叫匿名函数。
普通函数与匿名函数的对比:
普通函数
1 | def add(a,b): |
匿名函数
1 | add = lambda a,b : a + b |
从上面看不出来本质的区别,匿名函数主要是和其它函数搭配使用:
1 | res = map(lambda x: x ** 2, [1, 5, 7, 4, 8]) |
执行后输出为:
1 | 1 |
匿名函数有个限制,就是只能有一个表达式,不用写 return,返回值就是该表达式的结果。
用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数:
1 | lambda x : x * x lbd = |
同样,也可以把匿名函数作为返回值返回,比如:
1 | def build(x, y): |
递归函数
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。
例如在计算阶乘 n! = 1 x 2 x 3 x ... x n
,用函数 fact(n)
表示 ,则 fact(n) = n! = 1 x 2 x 3 x ... x (n-1) x n = (n-1)! x n = fact(n-1) x n
,所以 fact(n)
可以表示为 n x fact(n-1)
,只有 n=1
时需要特殊处理 :
1 | #!/usr/bin/env python3 |
计算 fact(5)
过程如下:
1 | ===> fact(5) |
使用循环的方式处理:
1 | #!/usr/bin/env python3 |
递归函数的优点:
- 定义简单,逻辑清晰。理论上所有的递归函数都可以写成循环的方式,但循环的逻辑不如递归清晰。
递归函数的特性:
必须要有一个特定的结束条件。
每次进入更深一层递归时,问题规模相比上次递归都应有所减少。
递归函数在很多情况下效率会很低,并且递归层次过多会导致栈溢出,堆栈扫盲 。
练习
练习一: 斐波那契数列(Fibonacci sequence ): 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ........
- 定义一个函数,接收一个参数 n
- 从第 3 项开始,每一项都等于前两项之和
- 调用函数时返回第 n 项 的结果,例如
n = 8
时,对应的项是21
循环法:
1 | #!/usr/bin/env python3 |
递归法:
1 | #!/usr/bin/env python3 |
练习二: 已知 t1, t2 = ('a', 'b'), ('c', 'd')
,请使用 Python 中匿名函数生成列表 [{'a':'c'},{'b':'d'}]
。
1 | #!/usr/bin/env python3 |