如果你觉得我的文章写的不错,请关注我哟,请点赞、评论,收藏此文章,谢谢!
本文内容体系结构如下:
编写代码往往是为了实现特定的功能,如果需要使用功能多次,也要写同样的代码多次吗?答案是否定的。本文将讲解函数。当执行一个任务多次时,我们不需要反复编写完成此任务的代码,只需要调用执行该任务的函数。函数的使用会让程序更加简洁,可读性更强,更易于维护。
一、函数的基本概念
1.1 什么是函数?
函数是一段具有特定功能的代码块,它可以被多次调用以提高代码的复用性和可读性。函数可以接收输入参数,执行一系列操作,并返回结果。
1.2 为什么要使用函数?
- 代码复用:避免重复编写相同的代码。
- 模块化:将复杂的程序分解为小的、易于管理的部分。
- 可读性:函数使代码更易于理解和维护。
1.3 展示函数的好处
(1)示例代码
# 需求:求指定范围内所有整数的和
# 1:求1-10之间所有整数的和
sum = 0
i = 1
while i<=10:sum+=ii+=1
print("1-10之间所有整数之和:",sum)# 1:求5-20之间所有整数的和
sum = 0
i = 5
while i<=20:sum+=ii+=1
print("5-20之间所有整数之和:",sum)print("--------------------------------------------")# 定义一个函数求指定区间内所有整数之和
def sum(num1,num2): # 假设num1<=num2sum=0startNum = num1while startNum<=num2:sum+=startNumstartNum+=1print(f"{num1}到{num2}之间所有整数之和:{sum}")# 调用函数求1-100之间所有整数之和
sum(1,100)
sum(1,10)
sum(5,20)
从上面代码可知,没有使用函数之前,每求一次指定范围内所有整数之和,都需要将使用循环求和的代码写一遍。使用了函数之后,将循环求和的代码封装到函数中,要求和时只需要调用函数,传递指定范围的区间数据就可以输出结果,实现了代码复用,提高了代码编写效率。
(2)执行结果
二、函数的定义
2.1 语法结构
def 函数名([参数列表]):函数体[return 返回值列表]
def
:是定义函数的关键字。函数名
:是标识符,用于调用函数,不能与关键字重复。参数列表
:是传递给函数的变量列表,可以为空,小括号不能省略。定义函数的参数名为形式参数,简称形参,调用函数时传递的参数为实际参数,简称实参。函数体
:是实现特定功能的代码块,通常会缩进一级。- return:return语句可以省略,当需要返回值时,return语句是函数结束的标志,会将返回值列表返回给调用者。函数体中也可以使用return来结束函数体后续代码的执行,类似于break在循环中的作用
2.2 示例
# 定义函数,函数名为say_hello(),没有参数,没有返回值
def say_hello():print("Hello, World!")
三、函数的形参和实参
3.1 形参(形式参数)
- 定义:形参是函数定义中括号内的变量。
- 作用:用于在函数内部接收和存储传递给函数的值。
- 示例:
def my_function(param1, param2):
中,param1
和param2
是形参。
3.2 实参(实际参数)
- 定义:实参是调用函数时传递给函数的值。
- 作用:为函数提供所需的数据。
- 示例:
my_function(10, 20)
中,10
和20
是实参。
四、函数的调用
4.1 语法结构
函数名([参数])
- 通过函数名加上括号(可能包含参数)来调用函数。
4.2 示例
# 调用函数,通过函数名调用,函数输出:Hello, World!
say_hello() # 输出: Hello, World!
五、函数的参数传递
Python在调用有参数的函数时,需要传递参数,Python有多种方式传递参数:参数的位置传递要求实参的顺序与形参的顺序相同;参数的关键字传递中,实参由变量名和值组成;除此之外,还可以通过参数的包裹传递来传递任意个数的参数,等等。
5.1 参数的位置传递
按函数定义时的参数位置传递参数,传递的参数与函数定义时的顺序一致。如果没有按照位置传递正确的参数,得到的结果可能是不符合常理的。
注意:调用函数时,实参和形参的个数要一致,否则会报错。
示例
def showInfo(name,age,hobby):print(f"大家好!我叫{name},今年{age}岁了,我的爱好是{hobby}")# 按照函数定义时参数列表的顺序传参,才能输出正确的结果
showInfo("张三",20,"篮球") # 大家好!我叫张三,今年20岁了,我的爱好是篮球# 没有按照函数定义时参数列表的顺序传参,输出错误的结果
showInfo(19,"足球","李四") # 大家好!我叫19,今年足球岁了,我的爱好是李四# 按照函数定义时参数列表的顺序传参,但是多或者少传递了参数,报错
# showInfo("张三",20) # TypeError: showInfo() missing 1 required positional argument: 'hobby'
# showInfo("张三",20,"篮球","男") # TypeError: showInfo() takes 3 positional arguments but 4 were given
5.2 参数的关键字传递
调用函数时,传递参数通过参数名传递参数,顺序可以随意。
示例
def showInfo(name,age,hobby):print(f"大家好!我叫{name},今年{age}岁了,我的爱好是{hobby}")# 使用位置传参,传递参数时明确说明数据赋值给哪个参数,使用位置传参,参数顺序不需要和参数定义顺序一致
showInfo(name="王五",age=21,hobby="羽毛球") # 大家好!我叫王五,今年21岁了,我的爱好是羽毛球
showInfo(age=22,name="赵六",hobby="乒乓球") # 大家好!我叫赵六,今年22岁了,我的爱好是乒乓球
showInfo(hobby="足球",age=23,name="孙七") # 大家好!我叫孙七,今年23岁了,我的爱好是足球
5.3 参数的默认值传递
为参数提供默认值,调用时可以不传递该参数也可以传递参数,如果默认值参数不传递参数,则使用默认值,如果给默认参数传递了一个新的数据,则使用传递的新数据。
注意:定义函数时,默认参数可以有多个,但是有默认参数的应该放在没有默认参数的右边,否则函数会报错。
示例
def showInfo(name,age,hobby,grade="大一"):print(f"大家好!我叫{name},今年{age}岁了,我的爱好是{hobby}!我今年读{grade}")# 按照函数定义时参数列表的顺序传参,没有给grade参数赋值,使用默认值
showInfo("张三",20,"篮球") # 大家好!我叫张三,今年20岁了,我的爱好是篮球!我今年读大一
# 按照函数定义时参数列表的顺序传参,给默认参数重新赋值为大二,输出grade参数值为大二
showInfo(19,"足球","李四",grade="大二") # 大家好!我叫19,今年足球岁了,我的爱好是李四!我今年读大二# 使用位置传参,传递参数时明确说明数据赋值给哪个参数,使用位置传参,参数顺序不需要和参数定义顺序一致,默认值参数使用默认值
showInfo(name="王五",age=21,hobby="羽毛球") # 大家好!我叫王五,今年21岁了,我的爱好是羽毛球!我今年读大一
# 使用位置传参,传递参数时明确说明数据赋值给哪个参数,使用位置传参,参数顺序不需要和参数定义顺序一致,默认值参数重新赋值为“大二”
showInfo(age=22,name="赵六",hobby="乒乓球",grade="大二") # 大家好!我叫赵六,今年22岁了,我的爱好是乒乓球!我今年读大二
# 使用位置传参,传递参数时明确说明数据赋值给哪个参数,使用位置传参,参数顺序不需要和参数定义顺序一致,默认值参数重新赋值为“大三”,默认值参数可以随便放在哪个位置
showInfo(grade="大三",hobby="足球",age=20,name="孙七") # 大家好!我叫孙七,今年20岁了,我的爱好是足球!我今年读大三
5.4 参数的包裹传递
在定义函数时,如果不知道调用时会传递多少个实参,就可以使用Python提供的能够接收任意多个实参的传参方式,这就是参数的包裹传递。
5.4.1 *args
包裹传递
形参*args会让Python创建一个名为args的空元组,并将传入函数的实参全部存储在此元组中。函数接收不同类型的实参时,Python会先匹配位置实参和关键字实参,然后将余下的实参收集到最后一个形参中。
示例
def hobbys(name,*hobby):print(hobby,type(hobby)) # 查看参数hobby和它的数据类型print(f"{name}的爱好有:")for value in hobby:print(value)hobbys("张三","篮球")
hobbys("李四","篮球","足球")
hobbys("王五","羽毛球","棒球","滑雪")
输出结果如下:
5.4.2 **kwargs
包裹传递
形参**kwarg会让Python创建一个名为kwargs的空字典,并将传入的关键字实参存储在此字典中。函数接收不同类型的实参时,Python会先匹配位置形参,然后关键字形参,再是*
元组形参,最后才是**
字典形参,否则程序就会异常。
示例
def studentInfo(**info):return infoinfo1 = studentInfo()
print(info1) # {}
print(type(info1)) # <class 'dict'>info2 =studentInfo(sid=1001,name="张三",age=20,grade="大二")
print(info2) # {'sid': 1001, 'name': '张三', 'age': 20, 'grade': '大二'}
print(type(info2)) # <class 'dict'>
输出结果如下:
5.5 参数的解包裹传递
5.5.1 解包裹传递概念
星号(*)和双星号(**)除了在函数的形参中使用,还可以在调用函数时使用,作为实参进行传递,这就是参数的解包裹传递。
参数的解包裹传递机制:当实参为元组或列表时,将其拆分,使得元组或列表中的每一个元素对应一个位置形参;当实参为字典时,将字典拆分,使得字典中的每一个键值对作为一个关键字传递给形参。
5.5.2 示例1:实参为元组或列表
# 定义函数,传递3个值,输出3个值的乘积
def product(a,b,c):print(a*b*c)# 定义元组
tuple01 = (10,20,40)
# 调用函数,使用*传递元组
product(*tuple01)# 定义列表
list01 = [10,20,30]
# 调用函数,使用*传递列表
product(*list01)
输出结果如下:
注意:在调用函数传递元组或列表时,元组或列表中元素的个数要和函数的形参个数一致,否则会报错,请大家自行实验验证。
5.5.3 示例2:实参为字典
# 定义函数,传递3个值,输出3个值的乘积
def product(a,b,c):print(a*b*c)# 定义字典
dict01 = {"a":10,"b":20,"c":60}
# 调用函数,使用**传递字典
product(**dict01)
输出结果如下:
**注意:**在调用函数传递字典时,字典中的键名必须和函数中形参的名称保持一致,否则会报错,请大家自行实验验证。并思考有没有办法解决传递的字典名与函数的形参名不一致的问题。
六、函数的返回值
进行函数调用时,传递参数实现了从函数外部向函数内部的数据传输,而return语句则实现了从函数内部向函数外部输出数据。函数的返回值可以是空值、1个值或多个值,返回多个值时,多个值之间使用英文逗号,
隔开,返回的多个值你可以使用对应个数的变量去接收,也可以用一个变量接收,这个变量是一个元组变量。
如果定义函数时没有return语句,或者只有return语句而没有返回值,则Python会认为此函数返回的是None,None表示空值。
return语句可以在函数中的任何位置,当执行return语句时,函数停止执行,return语句后的代码不再执行。这个和break在循环中的作用一样。
6.1 语法结构
return 值1 [,值2,值3,...,值n]
6.2 示例1:返回None值
# 定义一个方法,没有返回值
def m1(num1,num2):print(num1+num2)result1 = m1(10,20) # 30
print(result1) # None
print(type(result1)) # <class 'NoneType'>
运行结果如下图所示:
6.3 示例2:返回1个值
# 定义一个方法,返回1个值
def m1(num1,num2):return num1+num2result1 = m1(10,20)
print(result1) # 30
print(type(result1)) # <class 'int'>
运行结果如下图所示:
6.4 示例3:返回多个值
# 定义一个方法,返回1个值
def m1(num1,num2):return num1,num2result1 = m1(10,20)
print(result1) # (10, 20)
print(type(result1)) # <class 'tuple'>
运行结果如下图所示:
七、函数的注释
7.1 pass语句
当定义函数没有写函数体时,代码会高亮显示,表示语法有问题,程序无法顺利运行。
此时用pass语句代替函数体可以使整个程序能够正常运行。if、for、while等语句后的语句块,也可以使用pass语句进行占位。
假如现在需要知道一个年份是不是闰年,可以定义函数去实现合格功能,但是函数体的内容暂时还不确定,那么此时就可以用pass语句进行占位,具体代码如下:
def is_leap(year):pass # 如果没有pass语句,下面的print语句会报错print("上面的函数没有写函数体,但我依然能够输出")
查阅资料后,知道闰年的条件是:年份值能被4整除但是不能被100整除,或者年份值能被400整除。知道这个条件后,可以对函数进行完善。函数代码如下:
def is_leap(year):if year%4 == 0 and year%100 != 0 or year%400 == 0:return Trueelse:return False
7.2 函数注释
函数定义好后,函数体代码也完善了,如果暂时不使用该函数,可能过段时间再看这个函数体代码时,可能看不明白了,这时候可以在函数体的起始位置输入三个引号(单引号或者双引号都可以)进行函数注释(注意:在PyCharm中输入三个引号回车后,可以自动生成部分函数注释),也称之为文档字符串。文档字符串一般包含函数的功能、参数以及返回值。可以通过__doc__
属性查看文档字符串。
注意
添加文档字符串,引号可以是单引号或者双引号
添加文档字符串,引号一定要在函数体起始位置添加,其他地方添加无效
def is_leap(year):"""函数功能:判断年份是不是闰年:param year: 传递的年份值:return: 返回判断结果,返回值为布尔值,返回True表示是闰年,返回False表示不是闰年"""if year%4 == 0 and year%100 != 0 or year%400 == 0:return Trueelse:return Falseprint(is_leap.__doc__)
运行结果如下图所示
八、变量作用域
变量在代码中起作用的范围称之为变量的作用域。根据变量作用域的不同,变量可以分为两种,一种叫做局部变量,一种叫做全局变量。
8.1 局部变量
局部变量是指在函数内部使用的变量,只在民数内部起作用。在函数执行结束后,局部变量将不复存在。局部变量示例代码如下:
def f1(a):return a
result = f1(2)
print(a)
上面代码中,a是存在于f1函数中的局部变量,仅在f1()函数中起作用。在f1()函数外使用print()语句打印变量a,代码会高亮显示,运行程序,程序出现异常,运行结果如下图所示:
异常信息提示变量a没有被定义,进一步说明变量a不能在的函数外使用,属于在函数内部使用的局部变量。
不同函数中的局部变量名称可以相同,且互不影响。
def f1(a):return a
def f2(a):return a
result1 = f1(10)
print(result1)result2 = f2(20)
print(result2)
运行结果如下图所示:
f10函数和f2()函数中的局部变量虽然都是a,但是两函数之间并不影响,运行的结果也与预期相符。
8.2 全局变量
全局变量是指在函数之外定义的变量,能在整个程序中使用。
a = 10
def f3():print(a)
f3()# 函数中可以输出a的值
print(a) # 函数外可以输出a的值
输出结果如下图所示:
变量a是定义在函数f3()之外的全局变量,所以在f3()函数中可以获取全局变量a的值。但是在f3()函数中不能改变全局变量a的值,例如,在f3()函数中尝试给a的值增加20,运行程序会报错。
a = 10
def f3():a = a + 20print(a)
f3() # 执行报错
程序执行结果如下图所示:
程序异常的原因是,f3()函数有自己的内存空间,它将a=a+20语句理解为使局部变量a增加20,但是在f3()函数内部又没有定义局部变量a,a没有预先定义的值,增加20的操作就无法执行。
如果希望在函数里实现全局变量a加20,就需要f3()函数将a当作全局变量。使用关键字global可以声明该变量是全局变量。
8.3 关键字global
在函数f3()中将变量x声明为全局变量,就可以操作变量a增加20了。
a = 10
print(a) # 使用变量a之前,a的值为10def f3():global aa = a + 20print(a) # 30
f3() # 执行报错
print(a) # 30
运行结果如下图所示:
需要注意的是,当列表、字典等数据类型作为全局变量时,在函数内部可以对全局变量进行修改,不需要用global关键字进行声明。
dict01 = {"name":"张三","age":20,"gender":"男"}
def change_age():dict01["age"] = 21 # 函数内修改字典中键age对应的值为21,程序不报错print(dict01) # {'name': '张三', 'age': 20, 'gender': '男'}
change_age()
print(dict01) # {'name': '张三', 'age': 21, 'gender': '男'} 年龄值修改成功了
运行结果如下图所示:
注意:如果函数中定义了与外部全局变量同名的列表或字典,那么在函数内对列表或字典的操作,不会影响外部全局变量列表或字典等数据。这个请大家自行验证。
8.4 变量作用域总结
对于局部变量和全局变量,总结以下原则:
- 不可变的数据类型作为局部变量,仅能在函数内部创建和使用,函数执行结束后,变量就会被释放。如果全局变量中有与其同名的变量,不会受到影响。
- 不可变的数据类型可以用global关键字转换为全局变量,函数执行结束后,此变量能够保留且能改变同名全局变量的值。
- 当可变的数据类型作为全局变量时,如果在函数中没有创建同名的局部变量,则在函数内部可以直接使用并修改全局变量的值。
- 当可变的数据类型作为全局变量时,如果在函数中已经创建同名的局部变量,则函数内部仅对局部变量进行操作,函数执行结束后,局部变量被释放,不影响全局变量的值。
8.5 查看局部变量和全局变量
如果需要查看局部变量与全局变量,可以使用globalsO函数与localsO函数获取。
def fullUrl(url):url = "http://www." + url + ".com" # 局部变量print("局部变量:",locals())return urlurlStr = "cxyzxc" # 全局变量
urlInfo = fullUrl(urlStr) # 全局变量
print("全局变量:",globals())
代码执行结果如下:
F:\PythonDemo\.venv\Scripts\python.exe F:\PythonDemo\Demo.py
局部变量: {'url': 'http://www.cxyzxc.com'}
全局变量: {'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x00000240ECC084B0>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'F:\\PythonDemo\\Demo.py', '__cached__': None, 'fullUrl': <function fullUrl at 0x00000240ECBF7240>, 'urlStr': 'cxyzxc', 'urlInfo': 'http://www.cxyzxc.com'}进程已结束,退出代码为 0
globals0)函数和locals0)函数的返回值是字典,查看函数内部的局部变量需要在函数内使用locals(函数。全局变量的返回值中不但有自定义的全局变量,还有Pyihon内置的全局变量。
九、嵌套函数
嵌套函数是指在另一个函数内部定义的函数。Python允许你在一个函数体内再定义一个或多个函数,这些内部函数被称为嵌套函数。嵌套函数可以访问其外部函数的局部变量,但不能直接访问全局变量(除非使用global
关键字)。
9.1 嵌套函数示例
def f2():print("函数f2()开始执行...")def f1():print("函数f1()开始执行...")print("函数f1()结束执行...")# 调用函数f1()f1()print("函数f2()结束执行...")# 调用函数f2()
f2()
# f1() 只能在函数f2()中调用f1()函数,不能在函数f2()外调用函数f1()
运行结果如下所示:
F:\PythonDemo\.venv\Scripts\python.exe F:\PythonDemo\Demo.py
函数f2()开始执行...
函数f1()开始执行...
函数f1()结束执行...
函数f2()结束执行...进程已结束,退出代码为 0
上面示例中,只能在f2()函数中调用f1()函数,在f2()函数外不能对f1()函数进行调用。设想一下,如果在f2()函数中存在一个参数,那么f1()函数能对其进行使用吗?可以尝试一下。
def f2():x = 10def f1():print(x)# 调用函数f1()f1()# 调用函数f2()
f2()
执行结果如下:
F:\PythonDemo\.venv\Scripts\python.exe F:\PythonDemo\Demo.py
10进程已结束,退出代码为 0
如果在f1()函数中增加一个赋值语句x=x+1呢?此时程序会出现异常。可以发现,参数x对于f1()函数像是全局变量,但它又存在于函数之中,并不是全局变量。为了使f1()函数也能使用参数x,就不能再用global关键字了,而需要用nonlocal关键字。
9.2 nolocal关键字
在嵌套函数中,如果你想修改外部函数的变量(即非局部变量),你需要使用nonlocal
关键字来声明这个变量。nonlocal
关键字告诉Python,你引用的变量不是当前函数内的局部变量,也不是全局变量,而是更外层函数中的变量。
def f2():x = 10def f1():nonlocal xx = x+1print(x)# 调用函数f1()f1()# 调用函数f2()
f2()
运行结果如下所示:
F:\PythonDemo\.venv\Scripts\python.exe F:\PythonDemo\Demo.py
11进程已结束,退出代码为 0
在f1()函数中用nonlocal关键字对参数x进行声明后,f1()函数就可以操作x了。原本f2()函数中x的值为10,调用f1()函数使x增加1后,再输出x,x的值就变为11了。
注意事项
nonlocal
关键字只能在嵌套函数中使用,不能在外部函数或全局作用域中使用。- 如果你不小心在嵌套函数中修改了一个外部函数的变量而没有使用
nonlocal
关键字(且该变量不是全局变量),Python将会抛出一个UnboundLocalError
错误,告诉你该变量未被绑定(即未被声明为局部变量)。 - 使用
nonlocal
关键字时要小心,因为它允许你在嵌套函数中修改外部函数的变量,这可能会影响外部函数的其他部分或调用者的预期行为。
十、递归函数
10.1 什么是递归函数
递归函数是一种在函数体内调用自身的函数。换句话说,一个递归函数会先执行一部分操作,然后调用自己来处理剩余的部分,直到满足某个终止条件为止。递归函数在解决某些问题时非常有用,尤其是那些可以分解为类似子问题的问题。
10.2 递归函数的基本结构
递归函数通常具有两个主要部分:
-
基准情况(Base Case):这是递归的终止条件。当满足这个条件时,函数将停止调用自身并返回一个结果。如果没有基准情况,递归函数将永远调用自己,导致栈溢出错误。
-
递归步骤(Recursive Step):这是函数在基准情况之外执行的操作。它通常包括一些计算或数据处理,然后调用函数自身来处理剩余的部分。
10.3 递归函数的调用过程
递归函数的调用过程可以看作是一个“函数调用栈”的展开和收缩。每次函数调用都会将当前的状态(包括局部变量和参数)压入栈中,当函数返回时,状态会从栈中弹出。递归函数通过不断地调用自身来展开栈,直到达到基准情况开始收缩栈。
10.4 递归函数的应用示例
阶乘是一个经典的递归问题。n的阶乘(记作n!)是所有小于或等于n的正整数的乘积。例如,5! = 5 * 4 * 3 * 2 * 1 = 120。
def fact(n):# 基准情况:如果n是0,返回1if n == 0:return 1# 递归步骤:n的阶乘等于n乘以(n-1)的阶乘else:return n * fact(n - 1)# 测试递归函数
print(fact(5)) # 输出: 120
在这个例子中,fact
函数首先检查n
是否为0,如果是,则返回1(基准情况)。否则,它返回n
乘以fact(n - 1)
的结果(递归步骤)。这个过程会一直重复,直到n
减到0为止。
执行流程如下图所示:
10.5 递归函数的注意事项
- 确保有基准情况:没有基准情况的递归函数会导致无限循环和栈溢出错误。
- 避免过深的递归:虽然Python的递归深度限制可以通过
sys.setrecursionlimit
函数来调整,但过深的递归可能会导致性能问题甚至栈溢出。在某些情况下,使用迭代(循环)可能更高效。 - 理解递归调用:确保你清楚递归函数在每次调用时是如何处理输入并接近基准情况的。
十一、 Lambda函数
11.1 什么是Lambda函数
Lambda函数,也称为匿名函数(Anonymous Function),是一种简洁的定义函数的方式。它可以在需要函数对象的地方快速定义一个简单的函数,而不需要用def语句来显式地定义一个函数。Lambda函数通常用于需要将函数作为参数传递,或者函数足够简单以至于不需要用标准def语法来定义的情况。
11.2 Lambda函数的基本语法
Lambda函数的语法非常简洁,它的基本形式是:
lambda 参数1, 参数2, ... : 表达式
这里,lambda
是关键字,后面跟着的是函数的参数列表,冒号后面是一个表达式,这个表达式的计算结果就是函数的返回值。注意:Lambda函数只能有一个表达式,不能包含命令或多行代码。
11.3 Lambda函数的使用场景
- 作为高阶函数的参数:如
map()
,filter()
,sorted()
等函数可以接受函数作为参数,这时Lambda函数就非常有用。 - 快速定义简单的函数:当函数非常简单,只包含一行代码时,使用Lambda函数可以使代码更加简洁。
11.4 Lambda函数与常规函数的对比
特点 | Lambda函数 | 常规函数 |
---|---|---|
定义方式 | 使用lambda 关键字 | 使用def 关键字 |
函数名 | 无名(匿名) | 有名 |
代码行数 | 通常只有一行(表达式) | 可以有多行代码 |
返回值 | 表达式的计算结果 | 使用return 语句返回 |
可读性 | 较低(对于复杂逻辑) | 较高 |
11.5 Lambda函数的实际应用示例
11.5.1 使用Lambda函数进行排序
假设我们有一个包含多个元组的列表,每个元组包含一个人的名字和年龄。我们想要根据年龄对这个列表进行排序。
people = [('Alice', 30), ('Bob', 25), ('Charlie', 35)]# 使用lambda函数作为sorted的key参数
sorted_people = sorted(people, key=lambda person: person[1])print(sorted_people)
# 输出: [('Bob', 25), ('Alice', 30), ('Charlie', 35)]
11.5.2 使用Lambda函数和map函数
假设我们有一个数字列表,我们想要得到每个数字的平方。
numbers = [1, 2, 3, 4, 5]# 使用lambda函数和map函数
squared_numbers = list(map(lambda x: x**2, numbers))print(squared_numbers)
# 输出: [1, 4, 9, 16, 25]
11.5.3 使用Lambda函数和filter函数
假设我们有一个数字列表,我们想要过滤出所有的偶数。
numbers = [1, 2, 3, 4, 5, 6]# 使用lambda函数和filter函数
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))print(even_numbers)
# 输出: [2, 4, 6]
十二、总结
本文全面而详细地介绍了Python函数的相关知识,从函数的基本概念出发,阐述了函数在编程中的重要作用。通过具体示例,展示了如何定义函数、调用函数,以及如何通过不同的参数传递方式(如位置传递、关键字传递、默认值传递和包裹传递)来灵活地传递参数。同时,深入探讨了函数的返回值、注释的编写方法以及变量作用域的管理。
此外,本文还介绍了嵌套函数和递归函数的高级用法,展示了它们在解决复杂问题时的独特优势。最后,针对需要快速定义简单函数或作为高阶函数参数的场景,介绍了Lambda函数这一简洁的函数定义方式。
通过本文的学习,读者不仅能够掌握Python函数的基本使用方法和技巧,还能深入理解函数在编程中的核心地位和作用,为后续的编程实践打下坚实的基础。希望读者能够灵活运用所学知识,编写出更加高效、简洁、可维护的代码。