1.函数的定义及调用
函数定义:def 函数名(参数1,参数2=default......):
函数体
[ return 返回值 ] (可省略)
函数调用:函数名(参数1,参数2......)
注:1. 函数定义时用于接受的参数为形式参数;
2. 函数调用时传递的参数为实际参数。
3. default为默认值,当没有实际参数传入时该形式参数调用默认值。
4. 定义时,含默认值的参数必须在不含默认值的参数之后,否则报错。
def happy_birthday (name='小明',age): # 直接报错
def happy_birthday (name,age=18):
print(f'祝{name}')
print(f'{age}岁生日快乐')
happy_birthday('小明') # 祝小明 18岁生日快乐
2.位置传参与关键字传参
在调用函数时,传递参数的方法有两种:位置传参,关键字传参。
(1)位置传参:实际参数与形式参数个数和顺序必须相同,即一一对应。
(2)关键字传参:通过 形式参数=值 的方法传参,顺序可以不同。
注:两种传参方式共用时,必须位置参数在前,关键字参数在后
def happy_birthday (name,age):
print(f'祝{name}')
print(f'{age}岁生日快乐')
happy_birthday('小明',18)
happy_birthday(age=18,name='小明')
happy_birthday('小明',age=18)
# 祝小明 18岁生日快乐
# 错误示例
happy_birthday(age=18,'小明') # 报错
3.个数可变参数(*para与**para)
个数可变参数分为两种:个数可变的位置参数,个数可变的关键字参数。
(1)个数可变的位置参数:在函数定义时,形式参数前面加一个*(即*para),表示该形参可以接受多个位置实参,并形成一个元组存储这些实参;在函数调用时,实际参数前面加一个*,表示解包,可将单个可迭代对象中的多个元素拆分出来形成独立的实参,再传递给形参。
def fun1(*para):
print(para,type(para))
# 传递多个位置实参
fun1(11,22,33,44) # (11, 22, 33, 44) <class 'tuple'>
# 传递一个列表
fun1([11,22,33,44]) # ([11, 22, 33, 44],) <class 'tuple'>
# 将列表解包后再传递
fun1(*[11,22,33,44]) # (11, 22, 33, 44) <class 'tuple'>
(2)个数可变的关键字参数:在函数定义时,形式参数前面加两个*(即**para),表示该形参可以接受多个关键字实参,并形成一个字典存储这些实参;在函数调用时,实际参数前面加**,表示解包,可将字典拆分后再传递给形参。
def fun2(**kvpara):
print(kvpara,type(kvpara))
# 传递多个关键字实参
fun2(name='小明',age=18) # {'name': '小明', 'age': 18} <class 'dict'>
d = {'name':'小明','age':18}
# 传递一个字典
fun2(d) # 报错,必须先解包
# 将字典解包后再传递
fun2(**d) # {'name': '小明', 'age': 18} <class 'dict'>
4.可变对象与不可变对象的传参效果
不可变对象经函数调用后值不变(类似于c语言中的传值调用),可变对象经函数调用后值可以改变(类似于c语言中的传址调用)
# 以int为例,解释不可变对象
def add_numb(numb):
numb += 1
print(f'函数内numb的值为:{numb}')
numb = 10
add_numb(numb)
print(f'函数外numb的值为:{numb}')
# 函数内numb的值为:11
# 函数外numb的值为:10
# 以list为例,解释可变对象
def add_lst(lst):
lst[0] += 1
print(f'函数内的lst为:{lst}')
lst = [10,20,30]
add_lst(lst)
print(f'函数外的lst为:{lst}')
# 函数内的lst为:[11, 20, 30]
# 函数外的lst为:[11, 20, 30]
5.局部变量与全局变量的优先级
局部变量为函数内定义的变量,仅在函数内部生效,函数结束,其生命周期也同时结束;全局变量为函数外定义的变量或用global声明的变量,函数内外均生效,只有程序运行结束,其生命周期才结束。
注:当局部变量和全局变量同名时,局部变量优先级更高
def add_numb(numb):
a = 1
numb += a
print(numb) # 结果为11,局部变量优先
global a # 先声明,再赋值,遵循语法
a = 20
add_numb(10)
6.函数的返回值
若没有指定返回值,则默认返回值为None;若有多个返回值,则返回类型为元组,也可以进行解包赋值的方式分别赋值到不同的变量中。
# 1.默认返回值None
def add(a,b):
result = a+b
print(result) # 结果为30
fun_return = add(10,20)
print(fun_return) # 结果为None
# 因为函数体直接打印了结果,而没有设置返回值,返回值默认为None
# 2.返回多个值: 偶数和,奇数和,总和
def get_sum(numb):
sum = 0 # 总和
even_sum = 0 # 偶数和
odd_sum = 0 # 奇数和
for i in range(numb+1):
if i%2==0:
even_sum +=i
else:
odd_sum += i
sum += i
return(sum,even_sum,odd_sum)
# 直接接收结果为元组
sums = get_sum(10)
print(sums) # (55, 30, 25)
# 通过解包赋值的方式,分别赋值到不同的变量中
sum,even_sum,odd_sum = get_sum(10)
print(sum,even_sum,odd_sum) # 55 30 25
7.常用的内置函数
(1)sorted ( iter, key , reverse )
key的具体工作流程:key会接收一个函数,并将这个函数应用到可迭代对象的每一个元素上,生成一个比较键,之后python根据
比较键对该对象排序。
# 1.列表升降排序
lst = [12,35,75,2,86,7,46]
lst_sort = sorted(lst)
lst_sort_re = sorted(lst,reverse=True)
print('原列表:',lst) # 原列表: [12, 35, 75, 2, 86, 7, 46]
print('升序后列表:',lst_sort) # 升序后列表: [2, 7, 12, 35, 46, 75, 86]
print('降序后列表:',lst_sort_re) # 降序后列表: [86, 75, 46, 35, 12, 7, 2]
# 2.对集合sorted排序,会生成一个新列表存储
set = {12,35,75,2,86,7,46}
set_sort = sorted(set)
print(set_sort) # [2, 7, 12, 35, 46, 75, 86]
# 3.按字符串的长度进行排序
words = ['apple','banana','dog']
words_sort = sorted(words,key=len)
print(words_sort) # ['dog', 'apple', 'banana']
(2)reversed ( sequence )
lst = [12,35,75,2,86,7,46]
lst_re = reversed(lst)
print(lst_re) # <list_reverseiterator object at 0x0000014565A74790>
print(list(lst_re)) # [46, 7, 86, 2, 75, 35, 12]
(3)zip ( iter1 , iter2 )
注:zip对象只能被消耗一次,无法连续进行多次类型转换
lst1 = ['name','age','gender']
lst2 = ['小明',18,'男']
zipobj = zip(lst1,lst2)
print(zipobj) # <zip object at 0x000001FA32D57700>
print(list(zipobj)) # [('name', '小明'), ('age', 18), ('gender', '男')]
print(dict(zipobj)) # {},空集合,zip对象在上一步已经被消耗
print(dict(zip(lst1,lst2))) # {'name': '小明', 'age': 18, 'gender': '男'}
(4)enumerate ( iter , start )
words = ['apple','banana','dog']
words_index = enumerate(words,start=10)
print(words_index) # <enumerate object at 0x0000024CA2D07280>
print(list(words_index)) # [(10, 'apple'), (11, 'banana'), (12, 'dog')]
print(dict(words_index)) # {},空集合,enumerate对象在上一步已经被消耗
print(dict(enumerate(words,start=10))) # {10: 'apple', 11: 'banana', 12: 'dog'}
(5)filter ( function , iter )
def is_odd(numb):
return(numb%2 == 1)
lst = [12,35,75,2,86,7,46]
lst_odd = list(filter(is_odd,lst))
print(lst_odd) # [35, 75, 7]
(6)map ( function , iter1 , iter2... )
def add(x,y):
return(x+y)
numbers1= [10,20,30]
numbers2= [1,2,3]
result = list(map(add,numbers1,numbers2))
print(result) # [11, 22, 33]
8.匿名函数
python中的匿名函数用于编写简单的一次性函数,通过lambda定义,其语法规则为 lambda 形式参数:返回值表达式
注:匿名函数通常与map( ),filter( ),sorted( )函数结合使用,用于简化代码
numbers = [1,2,3,4,5,6]
# 1.单独使用匿名函数lambda,手动将列表numbers传递给形参x
for i in range(len(numbers)):
show_all = lambda x : x[i]
print(type(show_all)) # <class 'function'>
print(show_all(numbers)) # 1 2 3 4 5 6
# 2.结合函数map()使用,函数map()会将numbers的元素自动传递给形参x
numbers_squared = map(lambda x : x**2 , numbers)
print(list(numbers_squared)) # [1, 4, 9, 16, 25, 36]
# 3.结合函数filter()使用,函数filter()会将numbers的元素自动传递给形参x
numbers_odd = filter(lambda x : x%2==1 , numbers)
print(list(numbers_odd)) # [1, 3, 5]
# 4.结合函数sorted()使用,key会将列表的每个元素自动传递给形参x,用于生成比较键
students = [('Tom',18),('Jack',20),('Mike',15)]
students_sort = sorted(students,key=lambda x:x[1])
print(list(students_sort)) # [('Mike', 15), ('Tom', 18), ('Jack', 20)]