函数的参数
- 函数参数有:必选参数、位置参数、默认参数、可变参数、关键字参数、命名关键字参数……
- 组合使用时,它们的顺序:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。
位置参数
#定义一个函数来计算x^2
def power1(x) :
return x*x
#x就是一个位置参数
a = float(input('请输入一个数字:'))
print(power1(a))
#定义一个函数来计算x^n
def power2(x,n) :
return x**n
#x,n是两个位置参数,调用函数时,函数把获取的值,依次赋给x,n
m = float(input('请输入幂:'))
n = int(input('请输入次数:'))
print(power2(m,n))
请输入一个数字:2.5
6.25
请输入幂:3.14
请输入次数:2
9.8596
进程已结束,退出代码为 0
默认参数
问题:函数调用的时候只传入一个参数
#定义一个函数来计算x^n
def power2(x,n) :
return x**n
#x,n是两个位置参数,调用函数时,函数把获取的值,依次赋给x,n
m = float(input('请输入幂:'))
n = int(input('请输入次数:'))
print(power2(m))
请输入幂:2
请输入次数:5
Traceback (most recent call last):
File "D:…….py", line 12, in <module>
print(power2(m))
TypeError: power2() missing 1 required positional argument: 'n'
进程已结束,退出代码为 1
解决:用默认参数
def power2(x,n=2) : #默认计算x^2
return x**n
#x,n是两个位置参数,调用函数时,函数把获取的值,依次赋给x,n
m = float(input('请输入幂:'))
n = int(input('请输入次数:'))
print(power2(m))
请输入幂:5
请输入次数:4
25.0
进程已结束,退出代码为 0
默认参数更改默认值:
def power2(x,n=2) :
return x**n
#x,n是两个位置参数,调用函数时,函数把获取的值,依次赋给x,n
m = float(input('请输入幂:'))
n = int(input('请输入次数:'))
print(power2(m,n = n))
请输入幂:2
请输入次数:5
32.0
进程已结束,退出代码为 0
- 默认参数存在的问题:当默认参数为可变对象时
def l(list = []): #默认参数是一个空列表,列表是可变的
list.append('end')
return list #list指向的地址里存放的值会改变,而地址([])不变
print(l())
print(l())
print(l())
#应对:
def lw(list = None): #把list的空列表变成不可变对象
if list is None :
list = [] #然后赋值为空列表
else :
list.append('end')
return list
print(lw())
print(lw())
print(lw([1,2,3,4]))
['end']
['end', 'end']
['end', 'end', 'end']
[]
[]
[1, 2, 3, 4, 'end']
进程已结束,退出代码为 0
可变参数
-
可变参数:参数的数量是可变的
-
如何定义一个可变参数?在参数名字前加上“*”号
-
可变参数怎么处理参数?
可变参数,是把传入的参数组织成一个list或者是tuple,然后给定义的函数继续使用。 -
如何使用可变参数?
可以不给可变参数赋值,也可以赋很多值。
当已经有一个列表或者元组,要将其传入函数时,在list或者tuple前加一个“*”,它们里面的元素,就会被作为可变参数传入。
def func(*p) :
sum = 0
for i in p :
sum = sum+i
return sum
print(func(1,2,3,4,5),func(1,2,3))
List =list(range(1,11,1)) #如果已经有一个list了,怎么变成可变参数?
print(func(List[0],List[1])) #可以把里面的元素一个一个取出来作为可变参数
print(func(*List))#也可以通过高级手段
15 6
3
55
进程已结束,退出代码为 0
关键字参数
-
关键字参数怎么处理参数?
把赋值的,变成字典传入 -
怎么定义一个关键字参数?
在参数名字前加“**” -
如果传入的是一个字典?怎么变成关键字参数?
在字典名前面加“**”
def dix(name,age,**other) :
print('name:',name,'age:',age,'others:',other)
dix('yuyuan',21)
dix('yuyuan',21,city='hy',mcity ='xt') #这里的city不要用分号
kw = {'gender': 'F', 'job': 'Engineer'} #当已经有一个字典了,要传入
dix('yuyuan',21,gender = kw['gender'])
dix('yuyuan',21,**kw)
name: yuyuan age: 21 others: {}
name: yuyuan age: 21 others: {'city': 'hy', 'mcity': 'xt'}
name: yuyuan age: 21 others: {'gender': 'F'}
name: yuyuan age: 21 others: {'gender': 'F', 'job': 'Engineer'}
进程已结束,退出代码为 0
命名关键字参数
- 命名关键字参数如何定义?
用“*”作为分隔符,后面都是命名关键案子参数
或者前面已经有可变参数,可变参数后的参数都是命名关键字参数 - 命名关键字参数是如何处理传入值?
没有将其作为字典传入,而是普通的值。 - 如何使用命名关键字参数?
指定命名关键字的赋值,命名关键字参数都需要被赋值,同样也可以设置默认值。
def dix1(name,age,*,gender,city) : #*作为分隔符
print('name:',name,'age:',age,'others:',gender,city)
dix1('yuuan',21,gender='F',city='hy')
def dix2(name,age,*args,gender,city) : #前面有可变参数,后面的参数被默认为命名关键字参数
print('name:',name,'age:',age,'others:',gender,city,'yours:',args)
dix2('Rick',65,4,'Morty',gender='M',city='LOSA')
def dix3(name,age,*,gender='F',city) : #可以默认设置,但是没有默认设置时,不可以缺省
print('name:', name, 'age:', age, 'others:', gender, city)
dix3('yuuan', 21, city='hy')
name: yuuan age: 21 others: F hy
name: Rick age: 65 others: M LOSA yours: (4, 'Morty')
name: yuuan age: 21 others: F hy
进程已结束,退出代码为 0
参数组合
- 什么是参数组合?
在Python中定义函数,可以用必选参数、默认参数、可变参数、关键字参数和命名关键字参数,这5种参数都可以组合使用。 - 参数组合使用时候的注意事项? ——顺序
参数定义的顺序必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数。 - 参数组合的使用?
可以正常按照前面对这些参数进行赋值,也可以传入字典列表……
def mix(a,b,c=0,*args,city,**others) : #严格的顺序来定义参数组合
print('a=',a,'\t','b=',b,'\t','c=',c,'\t','city=',city,'\t','args=',args,'\t','others=',others)
#使用函数
mix(187,78,196,175,165,city='xt',brother = 'kuangyi',sister = 'huiyuan')
#当传入的是列表元组或者字典的时候,同样可以组合使用
l = [187,78,196,175,165]
d = dict(city='xt',brother = 'kuangyi',sister = 'huiyuan')
mix(*l,**d)
a= 187 b= 78 c= 196 city= xt args= (175, 165) others= {'brother': 'kuangyi', 'sister': 'huiyuan'}
a= 187 b= 78 c= 196 city= xt args= (175, 165) others= {'brother': 'kuangyi', 'sister': 'huiyuan'}
进程已结束,退出代码为 0
练习
- 以下函数允许计算两个数的乘积,请稍加改造,变成可接收一个或多个数并计算乘积:
- def mul(x, y):
return x * y
#多个数乘积
#多个数乘积
def mul(*num):
muls =1
if len(num) == 0 : #这里应该加一个判断做一下处理
raise TypeError('请输入值啊')
for i in num :
muls = muls * i
print(muls)
#函数调用
mul(1,2,3,4,5)
120
进程已结束,退出代码为 0
递归函数
- 使用递归函数的优点是逻辑简单清晰,缺点是过深的调用会导致栈溢出。
- 针对尾递归优化的语言可以通过尾递归防止栈溢出。尾递归事实上和循环是等价的,没有循环语句的编程语言只能通过尾递归实现循环。
- Python标准的解释器没有针对尾递归做优化,任何递归函数都存在栈溢出的问题。
# n! == (n-1)! * n ,把n! , (n-1)!作为函数,(n-1)! * n是n!的返回结果
def func1(n) :
if n==1:
return 1
return func1(n-1) * n
print(func1(5))
print(func1(10))
#尾递归: 将计算的结果作为函数返回的参数,而不是函数返回值本身
#把(n,p)作为函数,把计算的最终结果作为函数的参数去参与运算
def fun0(n) :
return func2(n,1)
def func2(n,product) :
if n == 1 :
return product
return func2(n-1,product*n)
print(fun0(5))
print(fun0(100))
120
3628800
120
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
进程已结束,退出代码为 0
练习
- 汉诺塔的移动可以用递归函数非常简单地实现。
- 请编写move(n, a, b, c)函数,它接收参数n,表示3个柱子A、B、C中第1个柱子A的盘子数量,然后打印出把所有盘子从A借助B移动到C的方法,例如:
- def move(n, a, b, c):
-
if n == 1: print(a, '-->', c)
#把n-1个盘子看成是一个整体,就是两个盘子在移动了
#第一步,把1,从a ---b , 第二步,把2,从a----c, 第三步,把1,从b--c
#迭代的是盘子的数量
def move(n,a,b,c) :
if n == 1 :
print(a,'---->',c)
else :
move(n-1,a,c,b)
move(1,a,b,c)
move(n-1,b,a,c)
tuple = ('A','B','C')
move(3,*tuple)
A ----> C
A ----> B
C ----> B
A ----> C
B ----> A
B ----> C
A ----> C
进程已结束,退出代码为 0