1.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(20, 10, 30) # a:20, b:10, c:30
# 关键参数
func1(a=100, b=200, c=300) # a:100, b:200, c:300
func1(b=200, c=300, a=100) # a:100, b:200, c:300
func1(100, c=300, b=200) # a:100, b:200, c:300
# func1(a=100, b=200, 300) # SyntaxError: positional argument follows keyword argument
# func1(100, a=200, c=300) # 传参必须保证每个参数都有值
2.参数默认值 - 形参
定义函数的时候可以直接给形参赋值,这样的参数就是有默认值的参数,在调用有默认值参数的函数时候,有默认值的参数可以不用传参。
注意:如果有的参数有默认值,有的参数没有默认值,那么没有默认值的参数必须在有默认值参数的前面
def func2(a=1, b=2, c=3):
# a = 10
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:1,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
def func4(a=10, b=20, c=30):
print(f'a:{a}, b:{b}, c:{c}')
func4(c=300) # a:10,b:20,c:300
# def func3(a=1, b, c): # SyntaxError: non-default argument follows default argument
# print(f'a:{a}, b:{b}, c:{c}')
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:定长在前,*的不定长在后,调用时候必须全部使用位置参数
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) # (2, 3, 4) {}
func7(a=10, b=20) # () {'a': 10, 'b': 20}
func7(2, 10, a=23, b=30) # (2, 10) {'a': 23, 'b': 30}
1.2返回值
1.返回值 - 将函数内部的数据传递到函数外部
什么时候需要返回值:如果实现函数的功能会产生新的数,那么新的数据就需要返回
def sum1(num1: int, num2: int):
s = num1 + num2
print('函数:', s)
sum1(10, 20) # 函数:30
2.怎么返回数据
1)return关键字后面的值就是函数的返回值 - 怎么确定函数返回值
2)函数调用表达式的值就是函数的返回值 - 怎么在函数外面获得函数返回值
def sum2(num1: int, num2: int):
s = num1 + num2
# print('函数:', s)
return s
result = sum2(10, 20)
r1 = print('result:', result) # result: 30
r2 = print(result * 100) # 3000
r3 = print([10, result]) # [10, 30]
print(r1, r2, r3) # None None None
3.return关键字
1)return 只能在函数体中使用
2)return用来将数据从函数的内部传递到函数外部,return后面的值就是函数的返回值。
如果没有return(没有遇到return),函数的返回值是默认的None
3)return可以直接结束函数 - 在执行函数体的时候,如果遇到return函数直接结束
def func2():
return 100
result = func2()
print(result) # 100
def func3():
print(100)
if 10 < 3:
return 200
print('返回值:', func3()) # 返回值:None
def func4():
print('start')
return
print('hello')
print('end')
func4() # start
- 返回值的使用
使用函数调用表达式的值就是使用函数的返回值
def func5():
return 100
# 1)可以直接打印函数调用表达式
print(100) # 100
print(func5()) # 100
# 2)可以使用函数调用表达式给变量赋值
a = 100
b = func5()
print(a, b) # 100,100
# 3)
print(100 + 200) # 300
print(func5() + 200) # 300
# 4)
list1 = [100, 200]
list2 = [func5(), 200]
print(list1, list2) # [100, 200] [100, 200]
def func6(string: str):
# string = 'hello'
return [x for x in string] # return ['h', 'e', 'l', 'l', 'o']
print(func6('hello')[-1]) # print(['h', 'e', 'l', 'l', 'o'][-1]) print('0')
1.3局部变量和全局变量
根据变量作用域的不同,将变量分为全局变量和局部变量
1.全局变量
没有定义在函数和类中的变量都是全局变量,全局变量从定义开始到整个程序结束(文件结束)的任何地方都可以用
# a是全局变量
a = 10
print('外部a:', a) # 外部a: 10
for _ in range(3):
print('循环里a:', a) # 循环里a: 10
def func1():
print('函数里面:', a)
func1() # 函数里a: 10
# b和c都是全局的
for b in range(3):
c = 100
print('循环里b、c:', b, c) # 循环里b、c: 0 100
print('循环外b、c:', b, c) # 循环外b、c: 2 100
def func2():
print(f'函数里bc:{b},{c}')
func2() # 函数里bc:2,100
- 局部变量
python中定义在函数中的变量就是局部变量,局部变量的作用域是从定义开始到函数结束。
def func3():
m = 10
n = 'abc'
print(f'函数中m、n:{m}, {n}')
func3() # 函数中m、n:10, abc
# print(f'函数外m、n:{m}, {n}') # 报错!
# 形参也是局部变量
def func4(x, y):
print('函数里面xy:', x, y)
func4(1, 2) # 函数里面xy: 1 2
总结:当调用函数的时候系统会自动为被调用的函数开辟一个临时的栈区间,用来保存在函数中定义变量。
当函数调用结束,这个函数对应的栈区间会自动释放,里面的数据会全部销毁,销毁之前会先将返回值返回
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.4匿名函数
匿名函数的本质是函数(匿名函数只能用来定义功能用一句代码就能实现功能的函数)
语法:
函数名 = lambda 形参列表: 返回值
相当于:
def 函数名(形参列表):
return 返回值
# 写一个匿名函数求两个数的和
sum1 = lambda num1, num2: num1 + num2
print(sum1(10, 20)) #
print(sum1(num1=100, num2=200)) # 300
# 练习:写一个匿名函数,判断指定的年是否是闰年。结果是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
print(is_leap_year(2020)) # True
print(is_leap_year(2021)) # False
1.作业
-
写一个匿名函数,判断指定的年是否是闰年
result = lambda year: year % 4 == 0 and year % 100 != 0 or year % 400 == 0 print(result(2021))
-
写一个函数将一个指定的列表中的元素逆序( 如[1, 2, 3] -> [3, 2, 1])(注意:不要使用列表自带的逆序函数)
def reversed_order(list1): new_list = list1[::-1] print(new_list)
-
写一个函数,获取指定列表中指定元素的下标(如果指定元素有多个,将每个元素的下标都返回)
例如: 列表是:[1, 3, 4, 1] ,元素是1, 返回:0,3def index1(list1,a): for x in range(len(list1)): if list1[x] == a: print(x)
-
编写一个函数,计算一个整数的各位数的平方和
例如: sum1(12) -> 5(1的平方加上2的平方) sum1(123) -> 14
def quadratic_sum(num1:int):
result = 0
for x in str(num1):
result += int(x)**2
print(result)
- 求列表 nums 中绝对值最大的元素
例如:nums = [-23, 100, 89, -56, -234, 123], 最大值是:-234
def max_nums(list1):
new_nums1 = []
new_nums2 = []
for x in list1:
if x >= 0:
new_nums1.append(x)
max_nums = max(new_nums1)
else:
new_nums2.append(x)
min_nums = min(new_nums2)
if max_nums >= -min_nums:
print('绝对值最大的元素为:',max_nums)
else:
print('绝对值最大的元素为:',min_nums)
-
已经列表points中保存的是每个点的坐标(坐标是用元组表示的,第一个值是x坐标,第二个值是y坐标)
points = [ (10, 20), (0, 100), (20, 30), (-10, 20), (30, -100) ]
1)获取列表中y坐标最大的点
for x in range(len(points)): max_points = points[0][1] if max_points < points[x][1]: max_points = points[x][1] max1 = points[x] print(max1)
2)获取列表中x坐标最小的点
for x in range(len(points)): min_points = points[0][0] if min_points > points[x][0]: min_points = points[x][0] min2 = points[x] print(min2)
3)获取列表中距离原点最远的点
for x in range(len(points)): max_points = points[0][0]**2+points[0][1]**2 if max_points < points[x][0]**2+points[x][1]**2: max_points = points[x][0]**2+points[x][1]**2 print(points[x])
4)将点按照点到x轴的距离大小从大到小排序