函数
函数可以认为是提供一种功能,当我们需要使用该功能时,就可以来调用该函数。
Python 中,函数可以分为两种:
内建函数:可以直接去访问的函数,例如 print,input,id,len 等
自定义函数:当我们需要的功能,Python 没有提供给我们时,我们可以自行来实现。
为什么使用函数:我们要实现的功能,未必只使用一次,有可能使用多次,甚至可能多人都需要使用。如果我们在每次使用该功能时,都给出对应的代码实现,就会造成代码重复。一旦代码重复,以后需求变更时,所有重复的代码都需要进行修改。此时程序非常难以维护。
需求:有效避免代码的重复? 答案:通过自定义函数实现
函数的优势:
- 函数实现了代码的重用,避免了代码的重复。以后功能变更时,只需要修改函数定义处即可,函数调用处不需要进行任何的改变。
- 函数有利于对程序进行模块的划分,便于协作式开发。
函数的定义
def 函数名(参数列表):
`函数体(即函数功能的实现)`
定义函数后,函数体是不会执行的,必须调用函数才能得到执行:函数名(参数列表)
当调用函数后,程序列成就会从调用函数的位置,跳转到函数定义位置,执行函数体。调用完毕后,程序流程返回函数调用处,继续执行后续的语句。
step in :进入函数调试
step out:从函数中出来
函数的参数
函数是具有一定功能大代码片段,函数的参数是对功能细节的调整做出的设置
在函数定义时,函数参数称为形式参数(行参),在函数调用时,提供的参数称为实际参数(实参),在函数调用过程中,实际参数会赋值给对应的形式参数。
#定义一个可以控制输出星星的行数和个数,并且可以将星星换成别的符号的函数
def print_start(lines,char,num_per_line):
for i in range(lines):
print(char*num_per_line)
#lines:输出的行数/ char:输出的字符/ num_per_line:每一行的字符数
#在调用函数时需要传递对应的参数值
print_start(2,'*',30)
尝试:通过函数交换变量的值——无法实现,因为
函数在调用时,实际参数仅仅是赋值给形式参数,而并非二者成为一体,因此,在函数内部,对形式参数做出的改变是不会反作用于实际参数的,但是可以改变实际参数所关联的内容。
def swap1(a,b):
c=a
a=b
b=c
但是可以通过列表来交换变量,因为 list 改变的是对象的内容,而不是改变实际参数所绑定哪个对象
def swap2(li):
li[0],li[1] = li[1],li[0]
函数的返回值
return
当函数具有返回值,相当于是函数的返回值,替换了调用的函数。
如果函数中没有显示使用 return 语句来返回结果,此时相当于是执行 return None。
函数中如果遇到了 return 语句,则会停止函数的执行,将 return 的结果返回给调用端。return 之后的语句将不会得到执行。
def 函数名(参数列表):
`函数体`
return 表达式
def add(a,b):
sum_=a+b
return sum_
#可以理解为将sum_赋值给result
result=add(5,3)
函数返回多个值
一个函数只能执行一条 return 语句,可以将多个值放入一个容器中,将容器返回。
def comput(a,b):
return a+b,a-b,a*b,a/b
返回的是元祖
指导思想:通常情况下,如果函数需要返回多个值,我们会将多个值放入一个元祖中,然后返回。因为元祖是不可修改的,可以防止调用端以外修改我们的数据
参数的默认值
参数多,函数调用时,也会比较繁琐,因此在定义函数的时候要为参数设置默认值。当参数具有默认值时可以选择性的传递。当我们为形参指定实参时,实参会赋值给形参,否则形参取定义时的默认值。
注意:可选参数必须定义在必选参数之后
参数可以具有默认值,也可以没有默认值。如果函数中有的参数有默认值,有的没有,则具有默认值的参数一定要定义在没有默认值的参数之后。
def 函数名(参数1=默认值1,参数2=默认值2,……)
`函数体`
def print_start(lines=2,char='*',num_per_line=20):
for i in range(lines):
print(char*num_per_line)
print()#参数具有默认值,因此可以不指定实际参数
有时候,函数的参数可能会很多,如果这些参数都需要用户进行设置,会带来很多的不便性。因此,我们可以为参数指定默认值。一旦参数具有默认值,该参数就是一个可选项,用户就可以选择性传递。
位置参数和关键字参数
如果用户只想设置第 3 个参数 num_per_line,将其设置为 30,而前两个参数取默认值,该如何做。
在 python 中,实际参数可以使用两种方式来指定
-
位置参数:对位传递,对位执行实参赋值给形参,
print_star(2,'*',30)
-
关键字参数:函数传递是以 参数名=参数值 的形式指定
print_star(lines=2,char='#',num_per_line=20)
关键字参数的优势
- 关键字参数比位置参数具有更好的可读性。
- 关键字参数可以不同考虑参数的顺序,只要参数名正确即可
- 关键字参数在多个参数具有默认值时,可以实现更灵活的传递与选择。
位置参数与关键字参数可以混合使用,如果混合使用,位置参数必须放在关键字参数之前。同时不要将同一个参数多次传值。
print_star(2,'#',num_per_line=20)
print_star(line=2,'#',30)
错误,关键字参数必须在位置参数之后。
print_star(2,line=2)
错误,line 这个参数穿了两次,同一个参数不能传多次
可变参数(不定长参数)
可变参数可以用来接收任意数量的位置参数或者关键字参数。
可变位置参数:参数名,底层是使用一个元祖来实现的,一般起名* args
可变关键字参数:参数名,底层是使用一个字典来实现的,*一般起名 kw*args
def add(*params):
sum_=0
for p in params:#元祖遍历
sum_+=p
return sum_
add()
add(1)
print(add(1,2,3,4,5,6))#多个参数
def fun(**kwargs):
#print(type(kwargs))
for k,v in kwargs.items():#字典遍历
print(k,v)
fun(a=1)
fun(a=1,b=2,c=3)#多个参数
可变关键字参数可以接受未匹配的关键字参数,如果关键字参数已经匹配,则无法传入可变关键字参数中。
def fun(a,**kwargs):
#print(type(kwargs))
for k,v in kwargs.items():
print(k,v)
fun(a=1,b=2,c=3) #执行结果只有b 2 和c 3,因为a=1已经赋值给a=1了
参数传递时的拆包操作
在传多个参数的时候,这些参数未必都是以单个变量的形式存在
,可能多个参数值存放在容器(列表,元祖,字典)中,此时需要将容器拆包,可以实现更方便的参数传递。
列表——*
def fun(a,b,c):
pass
li=['王同学','张同学','马同学']
fun(*li)
#星号相当于执行 fun(li[0],li[1],li[2])
字典——**
d={'a':'张三','b':'李四','c':'王五'}
fun(**d)
#两个星号相当于执行
fun(a='张',b='李',c='王')
例题:想要输出 t 中的元素,元素之间用#分隔,最后用&结尾
递归
递归是函数调用自身的过程
函数不会无条件调用自身。否则会达到最大深度,产生错误(RecursionError)。
递归的思想:递归采用分而治之的思想,着重于问题的拆解。我们通过递归,将大问题,拆解成小问题,小问题拆解成更小的问题,直到问题不需要再进行拆解,直接得出答案,我们将该答案进行回溯,一直回溯到最初的问题,问题得以解决。
递归调用的只是跟自己长的一样的函数,对自己本身并没有影响。
递归可以分为两个过程:
- 递推:将问题逐渐拆解,拆解成最小的问题,能够直接得到答案。
- 回溯:利用递推的答案,得到更大的问题的答案,直到解决最终的任务。
递归的通用写法:
def f(问题):
if 是否可以直接得到答案?(是否不进行拆解)
return 答案
问题拆解
f(小问题)
关于循环与递归
- 二者具有一定的相似之处,通常情况下,也能够解决同一个问题。但是,二者的思想是不同的。对于循环来说,考虑的是重复性操作。我们将同一个任务执行多次。
- 对于递归来说,考虑的是问题的拆解,将大问题拆解成更小的子问题。
循环与递归的对比
通常情况下,二者能够完成同一个任务
循环在执行时,不需要创建额外的数据结构,但是,递归涉及到函数的调用(对自身的调用),因此,在执行过程中,需要创建额外的栈。
但是有些任务,通过问题拆解来实现会比较简单,通过循环这种歌重复性的思想操作实现,会相对困难(例如汉诺塔),因此,此时应该优先使用递归实现。
例题:3 的阶乘,斐波那契数列、汉诺塔程序、输入一个字符串(字符不重复)输出该字符串的所有全排列
def factorial1(n):
if n==1:
return 1
else:
return factorial1(n-1) * n
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于