第5 章函数
学习目标
● 能根据功能定义函数并调用。
● 能理解匿名函数lambda的使用方法。
● 会根据需求使用全局变量和局部变量。
● 能理解递归的含义。
本章主要内容
各例题知识要点
例5.1 定义求阶乘的函数(函数定义) 
例5.2 定义求阶乘的函数,并调用该函数计算10的阶乘(函数定义与调用)

例5.无参函数)

3 定义一个无参数的问候函数
(
例5.4 定义包含参数的问候函数,调用该函数输出问候语(位置传递
)
例5.传递列表参数
)


5 定义函数问候列表中每一位用户
(
例5.传递列表参数
)


6 定义函数为列表中每项添加统一前缀
(
例5.关键字传递
)


7 定义描述宠物的函数
(
例5.可选参数
)


8 定义参数包含默认值的求和函数
(
例5.可变参数
)


9 定义参数不定长的函数
(
例5.10 用return返回多个值(函数返回值
)
例5.11 用return返回一个列表(函数返回列表
)
例5.12 用return返回一个字典(函数返回字典
)
例5.局部变量与全局变量
)


13 函数内外包含同名变量
(
例5.14 保留字global修饰变量(函数内使用全局变量
)
例5.局部变量为组合类型
)


15 局部变量为组合类型
(
例5.局部列表重新创建
)


16 函数内部创建局部列表变量
(
例5.a函数(匿名函数
)


17lambd
例5.递归
)


18 用递归方法定义求阶乘函数
(
例5.递归
)


19 用递归方法实现求斐波那契数列第10 个数
(
例5.递归
)


20 用递归方法实现二分查找函数( 

函数是一段具有特定功能的、可重用的代码。函数是功能的抽象,一般来说,每个函
数表达特定的功能。函数是带名字的代码块,用于完成具体的工作。需要使用函数的功
能时,可调用该函数。在程序中多次执行同一项任务时,不需要反复编写完成该任务的代
码,而只需调用执行该任务的函数即可。

使用函数的主要目的有两个:①降低编程难度;②代码复用。通过使用函数,程序
的编写、阅读、测试和修复将变得更加容易。
例如,数学中的组合是从
n 
个元素中不重复地选取
m 
个元素的一个组合,组合数的
计算如式(5-1)所示。
Am 

mnn!Cn 
=m!=n(5-1)

m!(-m)! 

从公式可以看出,计算组合数,需要多次计算阶乘。如果要变成实现计算组合数的功
能,可以把求阶乘的代码抽象出来,即定义为一个函数实现求阶乘的功能,然后在计算组
合数的过程中多次调用求阶乘的函数。使用函数既降低了编程难度,同时可以多次复用
相似代码,提高了代码效率。

5.函数的定义与调用
1 

1.函数的定义
5.1 
函数需要先定义后调用,函数的定义形式如下。


Python 
程序设计与应用


第5 章 函数 
def <函数名>(<0 个或多个参数>): 
<函数体> 
return <返回值> 
在函数的定义中,函数名是函数的标识。函数名后面是用圆括号“()”括起来的形式
参数列表,参数列表可以包含0个或多个形式参数。形式参数用来接收外部传递给函数
的数据,如果函数的运行不需要提供参数,则可以不要形式参数,此时圆括号中是空的。
但是,不管圆括号内的参数是否为空,圆括号本身都不能省略。函数体是实现函数功能所
需的若干条语句。
如果函数需要向外界返回结果,可以使用return语句。return后面可以列出0个或
多个数据。return后面没有数据时,return的作用是返回到主调语句,且不带回任何数
据。当return后面有一个数据时,将该数据作为结果带回。当return后面有多个数据
时,将把多个数据作为一个元组带回。
【例5.1】 定义求阶乘的函数。
【分析】 求阶乘函数要实现求某个数的阶乘,需要一个参数,求得的阶乘值,需要通
过return返回。
程序代码: 
def fact(n): 
s = 1 
for i in range(1, n+1): 
s *= i 
return s 
程序说明:变量n 是形式参数,计算得到的n 的阶乘,存放在变量s 中,通过return 
返回s 的值。
函数定义时,参数是输入、函数体是处理、return返回的结果是输出,即遵循IPO 流
程。定义函数时,圆括号中的参数是形式参数,没有具体的值。当函数被调用时,才会把
实际参数值传递给形式参数。
需要注意,函数定义后,如果不经过调用,不会被执行。
5.1.2 函数的调用
【例5.2】 定义求阶乘的函数fact,调用函数fact,求10的阶乘并输出。
【分析】 先定义一个求阶乘函数fact(n),然后将10作为实际参数,调用fact函数, 
输出函数返回值。
程序代码: 
#定义函数fact 
def fact(n): 
s = 1 
149

Python 程序设计与应用 
for i in range(1, n+1): 
s *= i 
return s 
#调用函数fact,求10! 
m=fact(10) 
print("10!={}".format(m)) 
程序运行结果: 
10!=3628800 
程序说明: 
(1)该程序运行从m =fact(10)开始,由于运行时调用了fact函数,则转向定义函数
的部分,将10传递给n。
(2)函数定义中的形参与函数调用中的实参是两个重要概念。函数定义里的变量n 
是形式参数。通过语句m =fact(10)调用函数,这里的10称为实际参数。
整个调用过程中数据的传递情况如图5-1所示。在函数调用过程中,实际参数10传
递给形式参数n,经过计算得到结果s=36288000,通过return将s 的值36288000返回, 
赋值给m 并输出。
图5-1 函数的调用过程
为了调用该函数求其他数的阶乘,可以先输入一个数,然后调用fact()函数求该数的
阶乘。即函数定义部分不变,调用的代码修改为: 
#调用函数fact,求n! 
n=eval(input()) 
m=fact(n) 
print("{}!={}".format(n,m)) 
如果输入5,则求得5的阶乘并输出。此时要注意,虽然这里使用了n 作为输入的变
量,与函数定义中的形式参数n 名称相同,但是含义不同,调用时输入的n 有实际的值, 
是实际参数。函数内外同名变量的区别会在5.4节中介绍。
5.2 函数的参数传递
函数可以有参数,也可以无参数。无参数传递的函数定义形式如下。
150

第5 章 函数 
def <函数名>() : 
<函数体> 
return <返回值> 
注意:即使没有参数,也必须保留圆括号。
【例5.3】 定义无参数的问候函数,调用该函数,输出问候语“Hello!”。 
deffunc(): 
print("Hello!") 
func() #调用func()函数
程序运行结果: 
Hello! 
这是一个无参数的函数,调用时不需要传入参数值。
5.2.1 位置传递
将例5.3稍做修改,就可以让函数func()不仅显示“Hello!”,还将打招呼的对象名字
显示出来。为此,可在函数定义func()的括号内添加一个参数username。通过在这里添
加username,就可以让函数接收给username指定的值。调用func()时,可提供名字作为
实际参数。
【例5.4】 定义问候函数,输入姓名和城市名,输出形如“你好,来自*的#同学!”的
问候语。其中,*表示城市名,#表示姓名。
程序代码: 
#定义函数
def func(name,city): 
return "你好,来自"+city+'的'+ name+"同学!" 
#调用函数
n=input() 
c=input() 
print(func(n,c)) 
程序运行结果: 
张华
北京
你好,来自北京的张华同学! 
程序说明: 
151

Python 程序设计与应用
(1)分两行分别输入“张华”和“北京”,调用func()函数,返回指定的问候语并输出。
(2)函数中包括两个参数,参数传递时,按照形式参数定义的顺序,将n 和c 分别传
递给name和city。这种位置传递是使用较为普遍的方式。
除了传递简单的变量,还可以向函数传递组合数据,例如列表。将列表传递给函数
后,函数就能直接访问其内容。
【例5.5】 假设有一个用户列表,定义函数问候其中每一位用户。
【分析】 将一个名字列表传递给一个名为user()的函数,这个函数的功能是问候列
表中的每个人。
程序代码: 
def user (names): 
#向列表中每位用户都发出问候 
for i in names: 
msg = "Hello, "+i+"!" 
print(msg) 
usernames=["Mary","Kitty","Bill"] 
user(usernames) 
程序运行结果: 
Hello, Mary! 
Hello, Kitty! 
Hello, Bill! 
将列表传递给函数后,函数就可以对其进行修改。在函数中对这个列表所做的任何
修改都是永久性的,这让你能够高效地处理大量的数据。
【例5.6】 假设有一个魔术师名字列表,定义make_great()函数,为魔术师列表中的
每个魔术师名字前都加入“theGreat”。
程序代码: 
def make_great(names, new_names): 
for item in names: 
item = "the Great "+item 
new_names.append(item) 
names=['Bill','Andy','Joy','Lily','Bin'] 
new_names=[] 
make_great(names, new_names) 
for item in new_names: 
print(item) 
152

第5 章 函数 
程序运行结果: 
the Great Bill 
the Great Andy 
the Great Joy 
the Great Lily 
the Great Bin 
5.2.2 关键字传递
关键字实参传递是给函数同时传递形参名和实参值。直接在实参中将名称和值关联
起来,因此向函数传递实参时不会混淆。关键字实参让你无须考虑函数调用中的实参顺
序,还清楚地指出了函数调用中各个值的用途。
【例5.7】 定义一个描述宠物的函数describe_pet,包含宠物类型和名字两个参数,调
用该函数,分别输出宠物类型和名字。
程序代码: 
def describe_pet(animal_type, pet_name): 
print("I have a "+animal_type +".") 
print("My "+ animal_type+"’s name is "+pet_name+".") 
describe_pet(pet_name="kitty",animal_type="cat") 
程序运行结果: 
I have a cat. 
My cat..s name is kitty. 
程序说明:定义函数describe_pet()时,有两个形式参数,分别是animal_type和pet_ 
name。调用时,通过赋值直接将实际参数与形式参数的名称对应起来,根据每个参数的
名称传递,此时,关键字不需要遵守位置的对应关系。
用关键字实参传递时,关键字实际参数的顺序无关紧要。下面两个函数调用是等
效的。 
describe_pet(animal_type="cat", pet_name="kitty") 
describe_pet(pet_name="kitty", animal_type="cat") 
注意:关键字实参传递时务必提供正确的形参名。
5.2.3 可选参数
可选参数是定义函数时就指定默认值的参数。可选参数函数的定义形式如下。
153

Python 程序设计与应用 
def <函数名>(<非可选参数>, <可选参数>=<默认值>) : 
<函数体> 
return <返回值> 
注意:可选参数必须放在非可选参数的后面。
例如,下面例5.8的代码中b和c是可选参数,如果调用时没有提供新值,则b和c取
值为默认值3和5,如果调用时提供了新值,则可选参数取新值。
【例5.8】 定义求三个数和的函数,包含三个参数,其中两个是可选参数,默认值分别
是3和5。
【分析】 可选参数要放在非可选参数之后。
程序代码: 
def Sum(a,b=3,c=5): 
return a+b+c 
print(Sum(8)) 
print(Sum(8,2)) 
程序运行结果: 
16 
15 
程序说明:在本例中,函数Sum 共有三个参数,分别是a、b、c。其中,b 和c 是可选
参数,在定义时给定了默认值,分别是3和5。通过print(Sum(8))调用Sum 函数时,只
给了一个参数8,赋给a,因此b 和c 取默认值。而在通过print(Sum(8,2))调用时,给了
两个参数,则c 会取默认值5。
5.2.4 可变参数
如果函数定义时参数数量不确定,则可以将形式参数指定为可变数量参数。
可变参数传递函数形式如下。 
def <函数名>(<参数>,*b) : 
<函数体> 
return <返回值> 
其中,带星号*的参数即为可变参数,可变参数只能出现在参数列表的最后。一个可
变参数代表一个元组。有关元组的知识将会在本章后续小节中讲解。
【例5.9】 定义一个可变参数函数,输出学生的学号、姓名和喜爱的运动项目。
【分析】 每个学生喜爱的运动项目可能有多个,因此,运动项目考虑用可变参数
存储。
154

第5 章 函数
程序代码: 
def stu(num,name,*sports): 
print("num:",num,"name:",name,"sports:",sports) 
stu("2020001","Wang") 
stu("2020002","Li","running") 
stu("2020003","Zhao","running","skating") 
程序运行结果: 
num: 2020001 name: Wang sports: () 
num: 2020002 name: Li sports: ('running',) 
num: 2020003 name: Zhao sports: ('running', 'skating') 
程序说明:参数sports前面加星号,表示sports是可变参数。调用stu函数时,可以
不提供值给sports参数;也可以为sports指定一个参数值,如'running';也可以为sports 
提供两个或多个参数值,如r' unning'和s' kating'两个值。
5.3 函数的返回值
函数可以返回0个或多个结果,传递返回值用return保留字。如果不需要返回值, 
则可以没有return语句。return可以传递0个返回值,也可以传递任意多个返回值。
5.3.1 返回多个值
return可以传递一个或多个返回值,下面举例说明如何利用return 传递多个返
回值。
【例5.10】 编写函数,计算1~n 的总和以及平均值,并返回总和值及平均值。
【分析】 函数有两个返回值,分别是总和值和平均值。使用return返回两个值,并
用逗号分隔两个值。
程序代码: 
def func(n,m): 
s=0 
for i in range(1,n+1): 
s+=i 
return s,s/m 
s,ave=func(10,10) 
print(s, ave) 
程序运行结果: 
155

Python 程序设计与应用 
55 5.5 
程序说明: 
(1)在定义func()函数时,首先将两个值分别存放到形式参数n 和m 中,然后通过
for循环求得1~n 的和,并存放在变量s 中,最后函数返回s 的值及s 除以m 的商。程序
通过一个return返回了两个值。
(2)在调用func函数时,实际参数10,10分别传递给形式参数n 和m 。func函数计
算并返回和值55及商5.5。最后,输出带回的总和值及平均值。
5.3.2 返回组合数据
函数可以返回任何类型的值,包括列表和字典等较复杂的数据结构。
【例5.11】 假设列表中为一个班级所有学生的成绩,用函数返回三个最高分数。
程序代码: 
def func(arg): 
#对成绩列表进行排序,返回前三个成绩 
arg.sort(reverse=True) 
return [arg[0],arg[1],arg[2]] 
ls= func([68,86,56,98,57,95,56,45,97,56,45,87,2,87,54,97,56,45,77,65,99,22, 
37,48,55,64]) 
print('前三名成绩分别为{}、{}和{}'.format(ls[0],ls[1],ls[2])) 
程序运行结果: 
前三名成绩分别为99、98 和97 
下面举一个返回字典的例子。
【例5.12】 编写函数,接收姓名中名和姓两部分,返回一个表示人名的字典。
程序代码: 
#返回一个人名信息的字典
def build_namedic(first_name, last_name): 
name={'first':first_name, 'last': last_name } 
return name 
name = build_namedic('Weiwei', 'Wang') 
print(name) 
程序运行结果: 
156