Python机器学习
上QQ阅读APP看书,第一时间看更新

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!进行递归过程分解如下:

在使用递归时,需要注意以下几点。

● 递归就是在过程中或函数中调用自身。

● 必须有一个明确的递归结束条件,即递归出口。