回顾
# 字符串格式化
# 加法运算、格式占位符
print('%s-%d-%.1f' % (13,4,5) # 单个占位 可以不要小括号
f - string
print(f'{90:.2f} {786:,}=== {245:,.2%}')
'''
def 函数名(变量1,变量2,...):
函数说明文档
函数体
定义函数不会执行函数体,调用的时候才会执行
函数名(数据1,数据2,...)
函数调用过程:
第一步:回到函数定义的位置
第二步:传参(用实参给形参赋值,要保证每个变量都值)
第三步:执行函数
第四步:确定返回值
第五步:回到函数调用的位置接着往后执行
'''
总结
函数参数
- 位置参数和关键字参数
-
根据实参提供的不同,将实参分为位置参数和关键字参数
''' 1) 位置参数:调用函数的时候让实参和形参在位置上一一对应 2) 关键字参数:调用函数的时候以’形参名 = 值‘的形式确定形参对应的实参 3)位置参数和关键字参数混用:位置参数必须在关键参数前面,同时必须保证每个参数都会有一次赋值 '''
-
位置参数
def func1(x,y,z): print(f'x:{x},y:{y},z:{z}') func1(3,45,6)
-
关键字参数
func1(x=13,y=34,z=34)
-
混用 (位置参数必须在前面,同时必须保证每个参数都会有一次赋值
func1(12,23,z= 30) func1(12,23,34) # func1(x=12, 23, z=30) # SyntaxError: positional argument follows keyword argument
- 参数默认值
- 定义函数的时候可以直接在形参后面用= 给形参赋默认值
- 有默认值的参数,在调用的时候可以不用传参(end= 必须传参
- 如果有的参数有默认值 有的没有,有默认值的参数必须放在没有默认值的后面
def func2(x= 12,y=32,z=23):
print(f'x:{x},y:{y},z:{z}')
func2(23)
func2(z=23)
def func3(z,x= 12,y=32):
print(f'x:{x},y:{y},z:{z}')
func3(456) #x:12,y:32,z:456
3.参数类型说明
-
无默认值参数的类型说明 - :类型
-
有默认值的参数,默认值的类型就是参数对应的类型
def func4(x: str, y=''): x.split('\n') y.replace('you', 'me')
4.不定义参数
'''
1.)带*的不定长参数:在某个形参前加* 号,那么这个形参就是不定长参数,它可以接受任意多个实参
带*的参数本质就是一个元组,对应的实参是元组中的元素
注意:带*的不定长参数对应的实参必须用位置传参
2) 带** 的不定长参数:在某个形成前加**,那么这个形参就是一个不定长参数,它可以接受任意多个实参
带** 的参数本质就是一个字典,对应的关键字参数就是字典中的键值对
注意:** 的不定长参数对应的实参必须使用关键字参数传参
'''
-
定长参数在*的不定长参数前,定长和不定长都适用位置参数传参
# def func5(*x,*y): # 带两个*定义有错 def func5(*x): pass # func5(x = 23) #TypeError: func5() got an unexpected keyword argument 'x' func5(51,343,4,6) def func5(char ,*nums): print(char,nums)
-
定长参数在*的不定长参数后面,*后面的定长参数必须使用关键字传参
def func6(*char ,nums): print(f'char:{char},nums:{nums}') func6(23,45,nums='sd') #char:(23, 45),nums:sd
-
** 的使用 给任意多个关键字参数
def func9(**x): print(x) func9(s=2,y=34,d =34) # print(func9(s=2,y=34,d=34))
-
定长参数在**的不定长前,定长既可以用位置参数也可用关键字参数
# def func10(x,**y): # print(f'x:{x},y:{y}') # # func10(12,s=22,f=23) #x:12,y:{'s': 22, 'f': 23} # func10(a=12,s=22,f=23) #x:12,y:{'s': 22, 'f': 23}
-
定长参数不能放在**对应的不定长参数后面
-
带*的不定长可以和带’‘的不定常参数一起用,但是带’‘参数的后面
def func11(*x,**y): print(x,y) func11() #() {} func11(32,34,34) #(32, 34, 34) {} func11(s=32,d=34,c=34) #() {'s': 32, 'd': 34, 'c': 34} func11(32,d=34,c=34) #(32,) {'d': 34, 'c': 34}
函数返回值
- 返回值
- 返回值的作用就是将函数内部的数据传递到函数外部
-
怎么确定函数返回值-- 怎么将函数内部的数据传递到外部
在函数体中用return关键字返回返回值(一个函数只能返回一个值)
什么时候需要返回值:如果函数的功能产生了一个新的数据,将新的数据返回
-
怎么获取函数返回值
获取函数调用表达式的值就是获取函数返回值
函数调用表达式 --调用函数的语句
函数调用表达式的值就是函数的返回值,函数返回值能做的事情,函数调用表达式就能做
def sum2(num1, num2): # print(num1+num2) return num1+num2 result = sum2(13,45) print(result) def func1(): return 100 print(100) #100 print(func1()) #100 a= 100 b= func1() print(a, b) list1 = [100,func1()] print(list1) dict1 = {'a':100,'b':{func1()}} def func2(): return [24,45,6] list2 = [24,45,6] list1 = func2() list2.append(23) list1.append(13) print(list2,list1) #[24, 45, 6, 23] [24, 45, 6, 13] print(func2().append(78)) #None
-
函数的调用过程
''' 第一步:回到函数定义的位置 第二步:传参(用实参给形参赋值,这个时候要保证诶个参数都有值 第三步:执行函数体 第四步:执行完函数体的时候确定函数返回值 (看执行函数体的时候有没有遇见return,如果遇见return,return后面的值是什么, 函数值就是什么,并且在遇到return的时候函数直接结束。如果没有遇见return,函数返回值就h是None 第五步:回到的函数调用的位置(这个时候函数调用表达式的值才是函数的返回值 return 用在循环体中 会全部结束 break 只结束循环体 ''' def func3(): print('=====') return 100 print('+++++') print(func3()) # python的函数只有一个返回值 def func4(): return 12,4 #返回元组(12,4) print(func4()) #(12, 4) 返回一个值 x,y = func4()
# 练习:写一个函数通过指定方法来计算多个的结果 # operation('+', 10, 20, 30) -> 求: 10+20+30 # operation('*', 3, 4, 5, 6) -> 求 3*4*5*6 # operation('-', 10, 3, 4) -> 求: 10-3-4 # operation('/', 19, 2) -> 求 19/2 def operation2(operator:str, *nums): if not nums or operator not in ('+','-',"*",'/'): return None if operator == '+': sum1 = 0 for x in nums: sum1 += x return sum1 if operator == '*': sum1 = 1 for x in nums: sum1 *= x return sum1 if operator == '-': sum1 = nums[0] for x in nums[1:]: sum1 -= x return sum1 if operator == '/': sum1 = nums[0] for x in nums[1:]: sum1 /= x return sum1 print(operation2('+', 10, 20, 30) ) #60 print(operation2('*', 3, 4,5, 6)) #360 print(operation2('-', 10, 3, 4)) #3 print(operation2('/', 19, 2)) #9.5
变量的作用域
- 变量的作用域-- 已经定义过的变量能使用范围
- 根据变量的作用域不同,将变量分为全局变量和局部变量两种
- 全局变量
-
没有定义在函数里面或者类里面的变量就是全局变量
-
全局变量的作用域:从定义开始到程序结束的任何位置都可以用
#a,b,x都是全局变量 a = 23 for x in range(4): b = 23 print(f'循环里面a:{a},b:{b}') print(x) def func1(): print(f'循环里面a:{a},b:{b}') func1()
- 局部变量
-
定义在函数里的变量就是局部变量:
-
局部变量的作用域:从定义开始到函数结束
# c 和d 都是局部变量 def func2(c=2): d = 234 print(f'函数内部c:{c},d:{d}')
- 函数调用过程就是压栈过程
- 调用函数的时候,系统会自动在栈区间为这个函数创建一个临时栈区间,用来保存在函数产生的数据(局部变量)
- 当函数调用结束时,这个临时栈区间会自动释放(释放之前胡将返回值传递到临时栈区间的外部)
- global 只能在函数体里面用
-
在函数体中修改一个全局变量的值或在函数定义一个全局变量
-
global 变量名
使用变量
num = 30 def func3(): num = 40# 不是修改全局变量num的值而是定义一个新的局部变量 print(f'函数内部num:{num}') global m m = 23 #在函数中修改一个全局变量的值,需要先用global进行说明 print(f'函数内部num:{m}') global n n = 'asd' # buyong 不用global 临时栈释放后 就没值 func3() print(f'函数外部num:{num}') print(f'函数外部m:{m}') print(f'函数外部n:{n}')
作业
- 编写一个函数,计算一个整数的各位数的平方和
例如: sum1(12) -> 5(1的平方加上2的平方) sum1(123) -> 14
def square_sum(num):
'''
计算一个整数的各位数的平方和
:param num: 一个整数
:return:一个整数的各位数的平方和
'''
sum1 = 0
for x in str(num):
sum1 += int(x)**2
return sum1
print(square_sum(123))
- 写一个函数,求一个数字列表中绝对值最大的元素
例如:nums = [-23, 100, 89, -56, -234, 123], 最大值是:-234
def max_abs(list1):
'''
求一个数字列表中绝对值最大的元素
:param num: 数字列表
:return: 最大值
'''
list2 =[]
for x in list1:
if x > 0:
list2.append(x)
else:
list2.append(-x)
max1 = max(list2)
for x in list1:
if x in [max1, -max1]:
return x
print(max_abs([-23, 100, 89, -56, -234, 123]))
-
编写函数实现字符串join方法的功能,将指定序列中的元素通过指定字符串合并成一个新的字符串
def join_str(list1,str2): ''' 将指定序列中的元素通过指定字符串合并成一个新的字符串 :param str1: 指定序列 :param str2: 指定字符串 :return: 新字符串 ''' str3='' for x in list1: str3 += str(x) str3 += str2 return str3[:-1] print(join_str([4,45,465],'+'))
-
写一个函数实现列表extend的功能,将指定序列中的元素全部添加到指定列表中
def extend_list(list1:list,list2): ''' 将指定序列中的元素全部添加到指定列表中 :param list1: 指定序列 :param list2: 指定元素 :return: 新列表 ''' for x in list2: list1.append(x) return list1 print(extend_list([23,5,6],(223,35)))
-
写一个函数实现简易计算器的功能:输入第一个数字,输入运算符,输入第二个数字,计算结果。
执行过程1: 计算器: >10 >+ >20 =30 执行过程1: 计算器: >10 >x >20 =200 ....
def counter1(a,b:str,c): ''' 实现简易计算器的功能:输入第一个数字,输入运算符,输入第二个数字,计算结果。 :param a:第一个数字 :param b:运算符 :param c:第二个数字 :return: 计算结果 ''' if b == '+': return a + c if b == '-': return a - c if b == '*': return a * c if b == '/': return a / c print(counter1(1,'+',34))
-
已经列表points中保存的是每个点的坐标(坐标是用元组表示的,第一个值是x坐标,第二个值是y坐标)
points = [ (10, 20), (0, 100), (20, 30), (-10, 20), (30, -100) ]
1)获取列表中y坐标最大的点
def max_y(list1): sdsd=[] for x in list1: sdsd.append(x[1]) bj=max(sdsd) for y in list1: if y[1]==bj: return y print(max_y([(10, 20), (0, 100), (20, 30), (-10, 20), (30, -100)]))
2)获取列表中x坐标最小的点
def min_x(list1): st = [] for x in list1: st.append(x[0]) sd=min(st) for y in list1: if y[0] == sd: return y print(min_x([(10, 20), (0, 100), (20, 30), (-10, 20), (30, -100)]))
3)获取列表中距离原点最远的点
def dicton(points): list2 =[] for x in points: list2.append((x[0]**2+x[1]**2)** 0.5) dict = max(list2) for y in points: if dict == (y[0]**2+y[1]**2)** 0.5: return y print(dicton([(10, 20), (0, 100), (20, 30), (-10, 20), (30, -100)]))
4)将点按照点到x轴的距离大小从大到小排序
def dicton_x(points):
listY= []
for x in points:
listY.append(abs(x[1]))
listY.sort(reverse=True)
# print(listY)
for y in points:
for z in listY:
for d in (z,-z):
if y[1] == d:
return y
print(dicton_x([(10, 20), (0, 100), (20, 30), (-10, 20), (30, -100)]))