day10 函数的进阶
函数的参数
1.位置参数和关键字参数
实参按照传递方式的不同分为位置参数和关键字参数两种
1)位置参数
调用函数的时候让实参和形参一一对应(第一个实参给第一个形参赋值,第二个实参给第二个形参赋值…)
格式:数据1,数据2,数据3,…
2)关键字参数
让实参和形参通过关键字(形参名)对应
格式:形参名1=数据1,形参名2=数据2,…
3)关键字参数和位置参数混用
混用的时候位置参数必须在关键字参数前面
def func1(x, y, z):
print(f'x:{x}, y:{y}, z:{z}')
# 位置参数
func1(10, 20, 30) # x:10, y:20, z:30
func1(10, 30, 20) # x:10, y:30, z:20
# 关键字参数
func1(x=100, y=200, z=300) # x:100, y:200, z:300
func1(z=30, x=10, y=20) # x:10, y:20, z:30
# func1(x=100, y=200, y=300) # 报错!
# 混用
func1(10, z=30, y=20) # x:10, y:20, z:30
# func1(x=20, 40, z=60) # 抱错!位置参数必须在关键字参数的前面
2.参数默认值
定义函数的时候可以给以’形参名=数据’的形式给参数赋默认值,调用函数的时候有默认值的参数可以不赋值
注意:有默认值的参数必须在没有默认值参数的后面
def func2(x=1, y=10, z=100):
print(f'x:{x}, y:{y}, z:{z}')
func2(1, 2, 3) # x:1, y:2, z:3
func2(10, 20) # x:10, y:20, z:100
func2(10)
func2()
func2(y=200)
func2(z=300)
def func3(x, y, z=100):
print(f'x:{x}, y:{y}, z:{z}')
3.参数类型说明
定义函数的时候,可以对参数类型进行说明
1)赋默认值,默认值是什么类型,参数类型说明就是什么类型
2)形参名:数据类型
def func4(x=''):
pass
def func5(x: list) -> None:
x.append('100')
func5([])
4.不定长参数
在形参前加*或者加**,就可以让这个参数变成不定长参数。不定长参数的形参可以同时接受多个实参
1)带*的不定长参数
带*的参数会变成一个元组,元组中的元素就是对于的实参
注意:a.一个函数可以同时存在带 * 和不带 *的参数,如果不带 *的在带 *的后面,不带 *的参数必须使用关键字参数
b.带*的参数必须使用位置参数
2)带**的不定长参数
带**的不定长参数会变成一个字典;调用的时候用关键字参数传参,每个关键字就是字典的key,关键字后面的数据就是字典的value
注意:a.定义的时候定长参数必须放在**不定长参数的前面
b.带 * 和带 ** 的不定长参数可以同时存在,但是 *必须在 ** 前面。(如果同时存在可以让函数在调用的时候更加灵活)
def func6(*x):
print(f'x:{x}')
func6()
func6(10)
func6(10, 20)
func6(1, 2, 3, 4, 5)
函数的返回值
1.返回值
1)什么是返回值
返回值就是从函数内部传递到函数外部的数据。(如果实现函数的功能,产生了新的数据一般都需要将这个新的数据通过返回值返回)
2)怎么确定函数返回值
在函数体中通过return关键字来返回返回值:return 数据
注意:a.同一个函数中,只有一个return有效。(因为执行函数体的时候只要遇到return函数直接结束)
b.如果要在一个函数中返回多个数据,用能够保持多个数据的容器。常用元组:return 数据1,数据2,数据3,…
3)怎么在函数外部获取函数返回值
获取函数调用表达式的值就是获取函数的返回值。(返回值对应的数据能做的,函数调用表达式都可以做)
# 练习:删除指定列表中所有指定元素
# [1, 23, 4, 5, 1, 34, 2, 1] 删除元素 1 -> [23, 4, 5, 34, 2]
# 方法一:
def del_item(list1: list, item):
for x in list1[:]:
if x == item:
list1.remove(x)
nums = [1, 23, 4, 5, 1, 34, 2, 1]
del_item(nums, 1)
print(nums)
# 方法二:
def del_item2(list1: list, item):
new_list = [x for x in list1 if x != item]
return new_list
nums = [1, 23, 4, 5, 1, 34, 2, 1]
new_l = del_item2(nums, 1)
new_l.append('end')
print(new_l)
全局变量和局部变量
根据变量的作用域不同将变量分为全局变量和局部变量两种
1.全局变量
定义在函数和类外面的变量都是全局变量
全局变量的作用域:从定义开始到程序结束的任何地方都可以用
# a是全局变量
a = 10
# b、c是全局变量
for b in range(4):
c = 100
pass
for _ in range(3):
print(f'循环里面a: {a}')
print(f'循环里面b: {b}')
print(f'循环里面c: {c}')
def func1():
print(f'函数里面a:{a}')
print(f'函数里面b:{b}')
print(f'函数里面c:{c}')
func1()
print(f'外部a:{a}')
print(f'外部b:{b}')
print(f'外部c:{c}')
2.局部变量
定义在函数里面的变量是局部变量
作用域:从定义开始到函数结束
局部变量产生原因:每次调用函数的时候,系统会自动为被调用的这个函数在栈区间开辟一个独立的内存空间,专门用来保存在这个函数中定义的变量。当函数调用结束的时候这块内存空间会自动销毁。
def func3(m=10):
x = 'abc'
print(f'函数内部x:{x}')
print(f'函数内部m:{m}')
for _ in range(2):
print(f'函数内部x2:{x}')
func3()
3.global和nonlocal
1)global
global的作用:在函数中定义或者修改全局变量
用法:
global 变量名
变量名 = 值
2)nonlocbal
作用:在局部的局部中修改一个局部变量的值
nonlocal 变量名
变量名 = 值
# 1)使用global在函数中定义全局变量
def func4():
global z
z = 100
func4()
print(f'外部z:{z}')
# 2)修改全局变量的值(如果直接在函数内容给全局变量赋值,不会修改值,而是产生一个新的局部变量)
name = '张三'
def func5():
global name
name = '李四'
print(f'函数内部name: {name}')
func5()
print(f'函数外部name: {name}')
def func6():
age = 18
def func7():
nonlocal age
age = 20
print(f'局部的局部age: {age}')
func7()
print(f'局部age:{age}')
func6()
匿名函数
1.什么是匿名函数
匿名函数的本质还是函数;但是匿名函数只能通过一条语句来实现函数的功能。
1)语法:
函数名 = lambda 形参列表:返回值
相当于:
def 函数名(形参列表):
return 返回值
# 求两个数的和
# def sum1(num1, num2):
# return num1 + num2
sum1 = lambda num1, num2=3: num1+num2
print(sum1(10, 20))
print(sum1(num2=100, num1=200))
print(sum1(2))
# 写一个匿名函数func2, 功能是打印一个数的平方
func2 = lambda num: print(num**2)
# print(func2(3))
func2(3)
递归(了解)
1.什么是递归函数
在函数中调用函数本身的函数就是递归函数
作用:循环能做的,递归都可以做。(指导思想:能用循环解决的问题就不要递归)
递归思想次数:控制递归函数在指定次数后结束
count = 5
def func1():
global count
count -= 1
print('======')
if count == 0:
return
func1()
func1()
2.使用递归解决问题的步骤
第一步:像定义普通函数一样来定义函数
第二步:找临界值(找函数结束的条件)
第三步:找关系(找f(n)和f(n-1) - 找上次循环和本次循环之间的关系)
第四步:假设函数的功能已经实现,通过关系用f(n-1)实现f(n)的功能
# 用递归:1+2+3+...+N
# f(n) = 1+2+3+...+n-1+n
# f(n-1) = 1+2+3+...+n-1
# 关系:f(n) = f(n-1)+n
def sum1(n):
# 1.找临界值
if n == 1:
return 1
# 2.找关系
# sum1(n) = sum(n-1)+n
return sum1(n-1)+n
print(sum1(100))