4、参数匹配
Python的函数定义非常简单,但灵活度却非常大。除了正常定义的必选参数外,还可以使用默认参数、可变参数和关键字参数,使得函数定义出来的接口,不但能处理复杂的参数,还可以简化调用者的代码。
位置参数
def func(a,b,c):
print(a,b,c)
func(1,2,3)
#输出
1 2 3
默认参数
def func(a,b=2,c=3):
print(a,b,c)
func(1)
#输出
1 2 3
函数func的参数b和c在定义时就提供了值,称为函数的默认参数。
关键字参数
def func(a,b,c):
print(a,b,c)
func(a=1,b=2,c=3)
#输出
1 2 3
在调用函数时,指明函数内的形参名称,称为关键字参数
可变参数
可以利用参数*参数名(通常为args),接收任意数量的参数
def avg(a,b,c):
return (a+b+c)/3
def avg(score,*scores): #可以接收任意数量的参数,加一个参数是为了防止一个参数都不输入会报错
return (sum(scores)+score )/( len(scores)+1)
result = avg(88,89,90)
print(result)
#输出
89.0
其中scores接收的参数,scores是一个列表,可以通过*来解包,也可以直接使用。如果向将一个列表的全部元素传给的参数,只需要在函数调用时,在列表名前加上*。
可变参数:**kwargs(通常使用kwargs),可以接收任意数量的关键字参数,在函数内部被封装成dict。
emp ={
'name': 'Jerry',
'age': 22,
'job':'dev'
}
def display_employee(name,age,job):
print(name,age,job)
def display(**employee):
print(employee)
display_employee(name=emp['name'],age=emp['age'],job=emp['job'])
display(name=emp['name'],age=emp['age'],job=emp['job'])
display(**emp)
#输出
Jerry 22 dev
{'name': 'Jerry', 'age': 22, 'job': 'dev'}
{'name': 'Jerry', 'age': 22, 'job': 'dev'}
拓展内容:
命名关键字参数,可以查看廖雪峰教程讲解。
5、Lambda表达式(匿名函数)
当我们在传入函数时,有些时候,不需要显式地定义函数,直接传入匿名函数更方便。
#Lambda表达式
def hello(name):
print(name)
lambda name: print(name)
# 以上两个时相互等价的,函数的执行内容在冒号后面跟,相对比不同的是lambda定义的函数没有名称
# 可以将lambda表达式赋值给变量。
f = lambda name: print(name)
f2 = lambda x, y: x + y #return也不写
- 关键字lambda表示匿名函数,冒号前面的x表示函数参数。
- 匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。
- 用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突。此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数
#lambda应用,函数委托
def hello_chinese(name):
print('您好',name)
def hello_english(name):
print('hello',name)
while True:
name = input('请输入您的姓名或输入stop退出\n')
if name == 'stop':
break
language =input('请输入语言\n e表示英语\n c表示汉语\n')
if language == 'c':
hello=hello_chinese
elif language == 'e':
hello = hello_english
else:
hello = lambda name :print('没有语言',name)
hello(name)
也可将上述代码优化如下:
def hello_chinese(name):
print('您好',name)
def hello_english(name):
print('hello',name)
operation = {
'c':hello_chinese,
'e':hello_english,
'j':lambda name :print('nihao',name)
}
while True:
name = input('请输入您的姓名或输入stop退出\n')
if name == 'stop':
break
language =input('请输入语言\n e表示英语\n c表示汉语\n j表示日语\n')
operation.get(language)(name)
上述利用dict和lambda结合使用,可以模仿出“switch的功能”。
6、高级工具
那么函数名是什么呢?函数名其实就是指向函数的变量!对于abs()这个函数,完全可以把函数名abs看成变量,它指向一个可以计算绝对值的函数!(实质是函数的名是一个指向函数的地址,()是解析这个地址并运行内部代码)
既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数,在有些语言里,这也称为委托。上面的程序就是这个道理。
高级工具map
map()函数接收两个参数,一个是函数,一个是Iterable,map将传入的函数依次作用到序列的每个元素,并把结果作为新的Iterator返回。
for x in l:
res.append(x+5)
print(res)
#2、推导
res = [x+5 for x in l ]
print(res)
#3、map
def add_number(x):
return x +5
li=list(map(add_number,l))
print(li)
#输出
[6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
[6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
[6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25]
高级工具filter
和map()类似,filter()也接收一个函数和一个序列。和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。
l=list(range(1,21))
res = []
s=list(filter((lambda x:not x%2),l))
print(s)
s=list(filter((lambda x: x%2==0),l))
print(s)
#这种方法会有0产生,不方便
l=list(range(1,21))
s=list(map((lambda x: x if not x%2 else 0),l))
print(s[1::2])