4.3 两类特殊函数
Python程序设计经常会用到两类特殊的函数,一类是匿名函数,一类是递归函数。匿名函数没有函数名称,不像原来函数那样需要用def语句定义函数。当需要定义一个功能简单但不经常使用的函数来执行脚本时,就可以使用匿名函数,从而省去定义函数的过程。一个函数在内部可以调用其他函数,但有时为了实现特殊功能,需要在函数内调用当前函数本身,这个函数就是递归函数。
4.3.1 匿名函数
Python允许使用lambda语句创建匿名函数,lambda语句中,冒号前是函数参数,若有多个函数须使用逗号分隔;冒号后是返回值。lambda为定义匿名函数时的关键字,arguments为传入函数的参数,expression为返回值。匿名函数具体用法如下所示。
【例4-10】编写程序,使用lambda语句创建匿名函数。
参考程序如下:
程序运行结果如下:
上述匿名函数相当于下面的自定义函数。区别是匿名函数只是一条语句,不用def语句定义函数,没有return,冒号后面的表达式就是返回值。
使用lambda语句定义匿名函数,应该注意以下3点。
● lambda定义的是单行函数,如果需要复杂的函数,应使用def语句。
● lambda语句可以包含多个参数。
● lambda语句只能有一个表达式,不用写return,返回值就是该表达式的结果。
4.3.2 递归函数
在数学与计算机科学中,递归(Recursion)是指在函数的定义中使用函数自身的方法,即一个函数在内部调用当前函数本身。
1.递归基本步骤
每一个递归程序都遵循相同的基本步骤。
1)初始化算法。递归程序通常需要一个开始时使用的种子值(seed value)。要完成此任务,可以向函数传递参数,或提供一个入口函数,此函数是非递归的,但可以为递归计算设置种子值。
2)检查要处理的当前值是否已经与基线条件匹配(base case)。如果匹配,则进行处理并返回值。
3)使用更小的或更简单的子问题(或多个子问题)来重新定义答案。
4)对子问题运行算法。
5)将结果合并入答案的表达式。
6)返回结果。
2.主要应用范围
递归算法一般用于解决3类问题。
● 数据的定义是按递归定义的。例如Fibonacci数列。
● 问题解法按递归算法实现。例如回溯算法。
● 数据的结构形式是按递归定义的。例如树和图等。
3.递归优缺点
(1)优点
● 递归使代码看起来更加简洁、优雅。
● 可以用递归将复杂任务分解成更简单的子问题。
● 使用递归比使用一些嵌套迭代更容易。
(2)缺点
● 递归的逻辑很难调试和跟进。
● 递归算法解题的运行效率较低。在递归调用的过程中,系统为每一层的返回点和局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。
【例4-11】编写程序,使用递归方法求n的阶乘n!。
参考程序如下:
程序运行结果如下:
对5!进行递归过程分解如下:
在使用递归时,需要注意以下几点。
● 递归就是在过程中或函数中调用自身。
● 必须有一个明确的递归结束条件,即递归出口。