Bootstrap

Python函数(2)--递归与匿名函数

递归函数

递归函数是一种直接或间接地调用自身的函数。递归通常用于解决那些可以分解为更小、相似子问题的问题,如树的遍历、图的搜索、排序算法(如快速排序)等。递归函数有两个基本要素:

  1. 自己调用自己
  2. 有停止条件(有出口)

接下来我们通过两个例子来了解递归函数:

阶乘

通过递归函数实现1~10的阶乘:

现在我们来定义一个递归函数,一定记住两点:自己调用自己和有出口

def factorial(n):
	出口
    自己调用自己
	pass

出口

首先,满足什么条件能让阶乘计算完成后自己停止呐?

1~10的阶乘为(10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 )的乘积,所以是不是当n为1的时候,就可以停止啦,实现一下出口:

def factorial(n):
    if n == 1:
        return 1
    自己调用自己
    pass

第一个条件我们满足了,怎么让函数自己调用自己呐?

自己调用自己

既然1~10的乘积,那返回出来的值就是他们的乘积,即f(10) * f(9) * f(8) * f(7) * f(6) * f(5) * f(4) * f(3) * f(2) * f(1) ,

那我们来实现一下:

def factorial(n):
    if n == 1:
        return 1
    return n * factorial(n - 1)		
#返回值后,factorial(n - 1)还要接着返回调用自己计算

这样我们就成功利用递归函数实现1~10的阶乘啦!我们来调用试试看查看结果:

调用

if __name__ == '__main__':
    print(factorial(10))
-----------------------------
输出结果:
3628800

斐波那契数列(Fibonacci)

定义一个函数fib,能够指定数量n,生成著名的斐波那契数列(Fibonacci)。斐波那契数列:

1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ... 除第一、二个数之外,后一个数等于前两个数之和

出口

观察一下斐波那契数列,是不是当n == 1 或者n == 2时,函数返回值为1时,就结束啦?对滴,那我们编写一下出口:

    if n == 1 or n == 2:
        return 1

自己调用自己

斐波那契数列的规律为:除第一、二个数之外,后一个数等于前两个数之和,那我返回的值是不是就可以写成:

	return fib(n-1) + fib(n-2)

当我们指定数量n为5时,当5输入进去返回的是"fib(4) + fib(3)",fib(4)和fib(3)还需要调用函数接着返回输出。

调用

据上所述,整合一下两个条件,得到:

def fib(n):
    # 出口
    if n == 1 or n == 2:
        return 1
    # 自己调用自己
    return fib(n-1) + fib(n-2)

调用试试看:

if __name__ == '__main__':
    print(fib(10))
输出结果:
55		#斐波那契数列第十个数为55,输出成功

lambda匿名函数

在Python中,匿名函数是通过lambda关键字来定义的。lambda函数本质上是一个小的匿名函数,它可以接受任何数量的参数,但只能有一个表达式。这个表达式的计算结果会被自动返回。因为lambda函数的定义是表达式,所以它可以出现在Python允许表达式出现的任何地方。

表示语法

lambda arguments: expression

arguments是传递给函数的参数,可以有一个或多个,用逗号分隔。
expression是关于参数的单个表达式,其计算结果将作为函数的返回值。

单个参数

利用lambda匿名函数将输入的值都加1:

f = lambda x: x + 1		#x为输入的参数,x + 1为表达式
print(f(1))
------------------
输出结果:
2

多个参数

add = lambda x, y: x + y	#两个参数分别对应
print(add(5, 3))
--------------------
输出结果:
8

在高阶函数中使用

map()函数

map()函数是 Python 的一个内置函数,它接收两个参数:一个是函数,另一个是可迭代对象(如列表、元组等)。map() 函数会将传入的函数依次作用到可迭代对象的每个元素上,并返回一个map对象。

让我们将列表内每一个元素都做函数的操作:

if __name__ == '__main__':    
    # 将列表内每一个元素都做函数的操作
    b = list(map(lambda x: x ** 2, li))
    print(b)
-----------------------
输出结果:
[1, 4, 9, 16]

reduce()函数

reduce()函数被放置在functools模块中,使用时需要调用,用于对参数序列中元素进行累积。它接收两个参数:一个是函数,另一个是序列(或其他可迭代对象)。这个函数将把序列中的元素从左到右依次进行累积。

调用reduce()函数:

from functools import reduce 

表示语法:

对列表:

print(reduce(lambda x, y: x + y, [1, 2, 3, 4]))
#接受lambda函数,对列表[1, 2, 3, 4]进行函数操作
-------------------
输出结果:
10

理解:对参数序列中元素进行累积,即首先赋值x = 1,y = 2,进行函数操作之后得到3,此刻相当于列表变成[ 3, 3, 4],接着进行累加,此刻x = 3,y = 3,进行函数操作后得到6,此刻列表变成[ 6,4],接着进行同样操作,最后输出结果为10。

对字符串:

print(reduce(lambda x, y: y + x, "abcd"))
#对于字符串x + y与y + x 不同,字符串相加时直接合并在一起前后顺序不同结果不同
----------------------
输出结果:
dcba

理解:与对列表的累积操作相同。

总结

本篇介绍了:

递归函数:递归函数是一种直接或间接地调用自身的函数。

  1. 两个基本要素:自己调用自己,有停止条件(有出口)

lambda匿名函数:接受任何数量的参数,但只能有一个表达式。

  1. 单个参数使用
  2. 多个参数使用
  3. 在高阶函数中使用,比如:
    1. map()函数:将传入的函数依次作用到可迭代对象的每个元素上,并返回一个map对象。
    2. reduce()函数:把序列中的元素从左到右依次进行累积。
;