总结
函数的参数(重要):
1.位置参数和关键字参数 - 根据函数调用的时候实参的传递方式分类
1)位置参数 - 让实参和形参在位置上一一对应
2)关键字参数 - 调用时在实参前加‘形参名=’的结构
3)位置参数和关键字参数可以混用(但位置参数要在关键字参数前面)
def func1(a, b, c):
print(f'a:{a},b:{b},c:{c}')
# 位置参数
func1(10, 20, 30) # a:10,b:20,c:30
# 关键字参数
func1(a=100, c=300, b=200) # a:100,b:200,c:300
# 位置参数和关键字参数混用(位置参数要在前面)
func1(100, c=300, b=200) # a:100,b:200,c:300
# func1(a=100,200,300) #SyntaxError: positional argument follows keyword argument
# func1(100,a=200,c=300) #传参时一个参数只能赋一次值
2.参数默认值 - 形参
定义函数时可以直接给形参赋值,这样的参数就是有默认值的参数,有默认值的参数可以不用传参
注意:如果有的参数有默认值。有的参数没有默认值,那么没有默认值的参数必须在有默认值参数的前面
def func2(a=1, b=2, c=3):
print(f'a:{a},b:{b},c:{c}')
func2(10, 20, 30) # a:10,b:20,c:30
func2(10, 20) # a:10,b:20,c:3
func2(10) # a:10,b:2,c:3
func2() # a:10,b:2,c:3
def func3(a, b, c=3):
print(f'a:{a},b:{b},c:{c}')
func3(100, 200) # a:100,b:200,c:3
func3(100, 200, 300) # a:100,b:200,c:300
3.参数类型说明
方法一:在没有默认值的形参后加:‘:类型名’
方法二:形参默认值的类型就是对应的参数类型
def func4(a: list, b: int, c=''):
print(f'a:{a},b:{b},c:{c}')
4.不定长参数
1)带的不定长参数 - 在形参前加,那么形参就是一个不定长参数,可以同时接受多个实参
不定长参数本质就是元组,对应的多个实参是元组的元素
注意:
a. 不定长参数对应的形参调用的时候必须用位置参数赋值
2)带**的不定长参数 - 在形参前加,那么形参就是一个不定长参数,可以同时接受多个实参,本质就是字典
注意:必须关键字参数传参
# 案例:定义一个函数求多个数的和: sum1
# sum1(10, 20)、sum1(20, 78, 8), sum1(10, 9, 8, 7, 4)
def sum1(*nums):
s = 0
for x in nums:
s += x
print('和:', s)
sum1() # ()
sum1(1) # (1,)
sum1(10, 20) # (10, 20)
sum1(20, 78, 8) # (20, 78, 8)
sum1(10, 9, 8, 7, 4) # (10, 9, 8, 7, 4)
特别的情况1:定长在前,*的不定长在后,调用时候必须全部使用位置参数(否则会报错:SyntaxError: positional argument follows keyword argument)
def student_info(name, *score):
print(name, score)
student_info('小明', 200)
student_info('小花', 200, 23, 89)
特别的情况2:*的不定长在前,定长在后,调用的时候定长必须使用关键字参数,不定长参数必须使用位置参数
def student_info2(*score, name):
print(name, score)
student_info2(2, 90, 78, name='小花')
特别情况3:*后面的其他参数必须使用关键字参数
def func5(a, *, b):
pass
func5(a=10, b=20)
def func6(**x):
print(x)
func6() # {}
func6(a=10) # {'a': 10}
func6(i=100, j=200) # {'i': 100, 'j': 200}
func6(i=100, j=200, z=300, m=400) # {'i': 100, 'j': 200, 'z': 300, 'm': 400}
def func7(*args, **kwargs):
print(args, kwargs)
func7(2, 3, 4)
func7(a=10, b=20)
func7(2, 10, a=23, b=30)
局部/全局变量
1.全局变量
没有定义在函数和类中的变量都是全局变量,全局变量从定义开始到整个程序结束(文件结束)的任何地方都可以用
2. 局部变量
python中定义在函数中的变量就是局部变量,局部变量的作用域是从定义开始到函数结束。
形参也是局部变量
总结:当调用函数的时候系统会自动为被调用的函数开辟一个临时的栈区间,用来保存在函数中定义变量。
当函数调用结束,这个函数对应的栈区间会自动释放,里面的数据会全部销毁,销毁之前会先将返回值返回
3.global
作用:
1)在函数中修改全局变量的值
2)在函数中定义全局变量
age = 18
name = '小明'
def update():
global name
age = 20 # 不会修改全局变量的值,而是定义一个新的局部变量age
print(f'函数里面-年龄:{age}') # 20
name = '小花'
print('里面:', name)
global sex
sex = '男'
update()
print(f'外面-年龄:{age}') # 18
print('外面:', name)
print('外面:', sex)
匿名函数
1.什么是匿名函数
匿名函数的本质是函数(匿名函数只能用来定义功能用一句代码就能实现功能的函数)
语法:
函数名 = lambda 形参列表: 返回值
相当于:
def 函数名(形参列表):
return 返回值
写一个匿名函数求两个数的和
sum1 = lambda num1, num2: num1 + num2
print(sum1(10, 20))
print(sum1(num1=100, num2=200))
练习:写一个匿名函数,判断指定的年是否是闰年。结果是True或者False
is_leap_year(2020) -> True
is_leap_year(2021) -> False
is_leap_year = lambda year: year % 4 == 0 and year % 100 != 0 or year % 400 == 0
- 写一个匿名函数,判断指定的年是否是闰年
judge_leap_year=lambda year:True if (year%4==0 and year%100!=0) or year%400==0 else False
judge_leap_year1=lambda year:True (year%4==0 and year%100!=0) or year%400==0 #不用三目运算符也可以,因为返回值要求True or False
- 写一个函数将一个指定的列表中的元素逆序( 如[1, 2, 3] -> [3, 2, 1])(注意:不要使用列表自带的逆序函数)
def reversed_order(list1):
new_list=[x for x in list1[::-1]]
return new_list
list1=eval(input('输入指定序列:'))
print(f'该序列逆序为:{reversed_order(list1)}')
方法二:
def reversed_order(list1):
return list1[::-1]
方法三:
def reversed_order(list1):
l1=len(list1)
for i in range(l1//2):
j=l1-1-i
list1[i],list1[j]=list1[j],list1[i]
list1=eval(input('请输入序列;'))
reversed_order(list1)
print(list1)
结果:
- 写一个函数,获取指定列表中指定元素的下标(如果指定元素有多个,将每个元素的下标都返回)
例如: 列表是:[1, 3, 4, 1] ,元素是1, 返回:0,3
def index_specificed_element(list1:list,char):
l1=len(list1)
new_list=[i for i in range(l1) if list1[i]==char]
return new_list
list1=eval(input('请输入指定列表:'))
char=eval(input('请输入指定元素:'))
print('指定元素的下标有:',index_specificed_element(list1,char))
方法二:(如果题目改为需要同时判断多个给定字符在序列中的位置)
结果:
- 编写一个函数,计算一个整数的各位数的平方和
例如: sum1(12) -> 5(1的平方加上2的平方) sum1(123) -> 14
def sum_of_squares(str1):
sum1=0
if str1[0] in '+-': #可以判断第一个字符是否是‘+’ 或‘-’
str1=str1[1:]
for x in str1:
sum1+=int(x)**2
return sum1
str1=input('请输入一个整数:')
print(f'各位数的平方和为:{sum_of_squares(str1)}')
结果:
- 求列表 nums 中绝对值最大的元素
例如:nums = [-23, 100, 89, -56, -234, 123], 最大值是:-234
def max_absolute_value(list1:list):
max1=max(list1)
min1=min(list1)
return max1 if max1>abs(min1) else min1
list1=eval(input('请输入指定序列:'))
print(f'该序列绝对值最大的数为:{max_absolute_value(list1)}')
结果:
- 已经列表points中保存的是每个点的坐标(坐标是用元组表示的,第一个值是x坐标,第二个值是y坐标)
points = [(10, 20), (0, 100), (20, 30), (-10, 20), (30, -100)]
1)获取列表中y坐标最大的点
def point_y_max(list1):
max1=0
for i in list1:
x,y=i
if y>max1:
max1=y
for i in list1:
x,y=i
if y==max1:
print(i,end=' ')
print()
list1=eval(input('请输入待判断的坐标点:'))
point_y_max(list1)
结果:
2)获取列表中x坐标最小的点
def point_x_max(list1):
max1=0
for i in list1:
x,y=i
if x>max1:
max1=x
for i in list1:
x,y=i
if x==max1:
print(i,end=' ')
print()
list1=eval(input('请输入待判断的坐标点:'))
point_x_max(list1)
结果:
3)获取列表中距离原点最远的点
def point_distance_max(list1):
max1=0
for i in list1:
x,y=i
if x**2+y**2>max1:
max1=x**2+y**2
for i in list1:
x,y=i
if x**2+y**2==max1:
print(i,end=' ')
print()
list1=eval(input('请输入待判断的坐标点:'))
point_distance_max(list1)
结果:
4)将点按照点到x轴的距离大小从大到小排序
def point_order(list1):
max1=0
l1=len(list1)
for i in range(l1):
for j in range(0,l1-i-1):
if list1[j]<list1[j+1]:
list1[j],list1[j+1]=list1[j+1],list1[j]
return list1
list1=eval(input('请输入待判断的坐标点:'))
print(point_order(list1))
结果: