一、函数的定义与调用
函数定义语法:
def 函数名([参数列表]):
'''注释'''
函数体
注意事项
- 函数形参不需要声明类型,也不需要指定函数返回值类型
- 即使该函数不需要接收任何参数,==也必须保留一对空的圆括号 ==
- 括号后面的冒号必不可少
- 函数体相对于def关键字必须保持一定的空格缩进
- Python 允许嵌套定义函数
1、Python定义的特点
在Python中,定义函数时也不需要声明函数的返回值类型,而是使用return语句结束函数执行的同时返回任意类型的值,函数返回值类型与return语句返回表达式的类型一致。
不论return语句出现在函数的什么位置,一旦得到执行将直接结束函数的执行。
如果函数没有return语句、有return语句但是没有执行到或者执行了不返回任何值的return语句,解释器都会认为该函数以return None结束,即返回空值
例1、编写生成斐波那契数列的函数并调用
二、函数参数
函数定义时圆括弧内是使用逗号分隔开的形参列表(parameters),函数可以有多个参数,也可以没有参数,但定义和调用时一对圆括弧必须要有。
定义函数时不需要声明参数类型,解释器会根据实参的类型自动推断形参类型。
1、位置参数
位置参数(positional arguments)是比较常用的形式,调用函数时实参和形参的顺序必须严格一致,并且实参和形参的数量必须相同。
python
>>> def demo(a, b, c):
print(a, b, c)
>>> demo(3, 4, 5) #按位置传递参数
3 4 5
>>> demo(3, 5, 4)
3 5 4
>>> demo(1, 2, 3, 4) #实参与形参数量必须相同
TypeError: demo() takes 3 positional arguments but 4 were given
2、默认值参数
带有默认值参数的函数定义语法如下:
def 函数名(......,形参名=默认值):
函数体
python
def describe_pet(pet_name, animal_type='dog'):
"""显示宠物的信息"""
print(f"\nI have a {animal_type}.")
print(f"My {animal_type}'s name is {pet_name.title()}.")
describe_pet(pet_name='willie')
I have a dog.
My dog's name is Willie.
可以使用"函数名.defaults"随时查看函数所有默认值参数的当前值,其返回值为一个元组,其中的元素依次表示每个默认值参数的当前值。
python
>>> def say( message, times =1 ):
print((message+' ') * times)
>>> say.__defaults__
(1,)
3、关键参数
关键参数主要指调用函数时的参数传递方式,与函数定义无关。通过关键参数可以按参数名字传递值,明确指定哪个值传递给哪个参数,实参顺序可以和形参顺序不一致,但不影响参数值的传递结果,避免了用户需要牢记参数位置和顺序的麻烦,使得函数的调用和参数传递更加灵活方便。
python
>>> def demo(a, b, c=5):
print(a, b, c)
>>> demo(3, 7)
3 7 5
>>> demo(a=7, b=3, c=6)
7 3 6
>>> demo(c=8, a=9, b=0)
9 0 8
4、可变长度参数
可变长度参数主要有两种形式:在参数名前加1个 * 或2个 **
*parameter用来接受多个位置参数并将其放在一个元组中
**parameter接受多个关键参数并存放到字典中
*parameter
python
def make_pizza(*toppings):
"""打印顾客点的所有配料"""
print(toppings)
make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')
('pepperoni',)
('mushrooms', 'green peppers', 'extra cheese')
**parameter
我们有时候需要接受任意数量的实参,但不知道信息是什么样的,
例如用户会希望使用一些自定义信息来创建账户,此时可以:
python
def build_profile(cid, name, **user_info):
'''创建一个字典,其中包含我们知道的有关用户的一切'''
user_info['身份证'] = cid
user_info['姓名'] = name
return user_info
user_profile = build_profile('3706...', '张三', location='yantai',field='computer')
print(user_profile)
{'location': 'yantai', 'field': 'computer', '身份证': '3706...', '姓名': '张三'}
三、传递参数时的序列解包
传递参数时,可以通过在实参序列前加一个星号将其解包,然后传递给多个单变量形参
python
>>> def demo(a, b, c):
print(a+b+c)
>>> seq = [1, 2, 3]
>>> demo(*seq)
6
>>> tup = (1, 2, 3)
>>> demo(*tup)
6
>>> dic = {1:'a', 2:'b', 3:'c'}
>>> demo(*dic)
6
>>> Set = {1, 2, 3}
>>> demo(*Set)
6
>>> demo(*dic.values())
abc
如果函数实参是字典,可以在前面加两个星号进行解包,等价于关键参数
python
>>> def demo(a, b, c):
print(a+b+c)
>>> dic = {'a':1, 'b':2, 'c':3}
>>> demo(**dic)
6
>>> demo(a=1, b=2, c=3)
6
>>> demo(*dic.values())
6
四、Lambda表达式
lambda表达式可以用来声明匿名函数,也就是没有函数名字的临时使用的小函数,尤其适合需要一个函数作为另一个函数参数的场合。也可以定义具名函数。
lambda表达式只可以包含一个表达式,该表达式的计算结果可以看作是函数的返回值,不允许包含复合语句,但在表达式中可以调用其他函数。
python
>>> f = lambda x, y, z: x+y+z #可以给lambda表达式起名字
>>> f(1,2,3) #像函数一样调用
6
>>> g = lambda x, y=2, z=3: x+y+z #参数默认值
>>> g(1)
6
>>> g(2, z=4, y=5) #关键参数
11
>>> L = [1,2,3,4,5]
>>> print(list(map(lambda x: x+10, L))) #模拟向量运算
[11, 12, 13, 14, 15]
>>> L
[1, 2, 3, 4, 5]
>>> data = list(range(20)) #创建列表
>>> data
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> import random
>>> random.shuffle(data) #打乱顺序
>>> data
[4, 3, 11, 13, 12, 15, 9, 2, 10, 6, 19, 18, 14, 8, 0, 7, 5, 17, 1, 16]
>>> data.sort(key=lambda x: x) #和不指定规则效果一样
>>> data
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> data.sort(key=lambda x: len(str(x))) #按转换成字符串以后的长度排序
>>> data
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> data.sort(key=lambda x: len(str(x)), reverse=True)
#降序排序
>>> data
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]