- 函数
- 如何定义函数
- 函数的调用和使用
- 带参函数
- 函数的返回值
- 函数的嵌套
- 函数的作用域(全局变量与局部变量)
- 全局变量
- 局部变量
- 缺省参数
- 不定长参数
- *args
- **kwargs
- 自动拆包
- 函数的递归(重点)
- 匿名函数 lambda
- 匿名函数的定义
- 匿名函数的使用
- lambda函数的当作参数的使用
- 使用匿名函数对列表排序
- 使用匿名函数对字典的排列
- sortde ( ) 函数
提到函数,自然想到上学时数学老师课堂上的函数,没错,计算机语言中的函数与数学中的函数非常相似,拿来就可以使用的公式一样,提前封装好的,可以重复里用的代码片段,如print函数,type函数。
所以我们定义函数的原因就是提升代码的结构化与可重复性。
格式:def + 函数名称+(参数):
参数可有可无,根据实际情况使用。
def 函数名 (参数):
代码块
return 结果
# 定义一个函数
def name():
print("你本优秀")
函数的调用和使用
调用函数之前,必须声明函数,否则无法调用,这个函数的基本结构完成以后,你可以通过另一个函数调用执行,也可以直接从Python提示符执行。
def 函数名 (参数):
代码块
return 结果
# 定义一个函数
def name():
print("你本优秀")
# 调用函数
name()
"""
输出结果
你本优秀
"""
带参函数
函数的参数分为实参和形参:
形参:就是形式上的参数,可以理解为数学的X,没有实际的值,通过别人赋值后才有意义。相当于变量。
实参“就是实际意义上的参数,是一个实际存在的参数,可以是字符串或是数字等。
注意:常规而言,函数默认有几个形式参数,在外部调用时就需要传递多少个实参
# 定义不带形参函数
def test():
a = 1
b = 2
c = a + b
print("{}+{}={}".format(a,b,c))
# 调用函数
test()
# 定义带形参函数
def test_01(a,b):
c = a + b
print("{}+{}={}".format(a,b,c))
# 调用函数,计算2加4的值
test_01(2,4)
函数的返回值
- 返回值:return ,返回值有无根据情况而定,没有return,返回值将是 None (空)。
- 返回值可以是任意类型。需要注意的是,return 语句在同一函数中可以出现多次,但只要有一个得到执行,就会直接结束函数的执行。
- 不设置返回值,函数最终执行的结果外界将无法使用,仅能在函数内部使用。
def value(a,b,c):
d = a * b * c
print("{}*{}*{}={}".format(a,b,c,d))
return d
# 调用函数,求三个数的乘积
value(1,2,3)
# 函数赋值给变量
d = value(1,2,3)
# 结果输出
print(d)
函数的嵌套
python中嵌套的思维不可少,前面学到的if嵌套,函数嵌套都是俄罗斯套娃的思维。在函数里面定义函数,而且现有的作用域和变量生存周期依旧不变。
def tset_1():
user_age = input("小王")
print("测试1.1")
print("测试1.2")
def test_2():
print("测试2")
tset_1()
print("测试2.1")
def test_3():
print("测试3")
test_2()
print("测试3")
tset_1()
print("测试3.3")
test_3()
"""
输出结果:
测试3
测试2
小王
测试1.1
测试1.2
测试2.1
测试3
小王
测试1.1
测试1.2
测试3.3
"""
函数的作用域(全局变量与局部变量)
- 作用域(Scope)就是变量的有效范围,有的变量可以在整段代码中使用,而有的代码只能在函数内部使用,有些变量只能在for循环中使用。
- 变量的作用域由变量的位置所决定的,不同位置定义不同作用域。
- 全局变量:在函数之外定义的变量,在任何函数之内都可以使用 注意:如果局部变量和全局变量重名,就近原则局部变量优先。
- global n :定义函数时调用全局变量时不能直接调用 先声明参数 n 。
x = 0
# 计算函数递归执行次数
# 定义一个递减相乘的函数
def overlay (i):
global x # 声明
x += 1 # 执行一次加一
if i >=0:
return 1
else:
return i * overlay(i - 1)
# 调用函数
overlay(5)
# 递归次数
print("递归次数为:{}".format(x))
"""
# 执行结果
120
递归次数为:6
"""
局部变量
- 在函数内部定义的变量,它的作用域也仅限于函数内部,出了函数就不能使用了,我们将这样的变量称为局部变量(Local Variable)。
- nonlocal n:如果两个嵌套函数,一个函数A里面又包含了一个函数B,那么对于B中的名称来说A中的作用域就为nonlocal。如果要在内层函数中修改外层变量,则需要用到 nonlocal 关键字
# 定义一个嵌套函数(闭包函数)
def outer():
num = 1
print(num)
def inter():
nonlocal num # 声明函数
num = 10
print(num)
inter()
outer()
"""
输出结果:
1
10
"""
缺省参数
- 在定义函数时,可以给某个参数定个默认值,具有默认值的参数称为缺省参数。
- 在一个函数中,没有定义缺省参数,在调用函数时就是使用定义参数时指定的参数默认值。
- 缺省参数只能放在常规形式参数的后面。
# 定义一个函数
def sum(a,b):
c = a+b
print("%d+%d=%d" %(a,b,c))
# 调用函数
sum(1,10)
不定长参数
当我们在不确定传入函数个数的时候,我们可以在定义函数的时候,添加不定长参数。
# print函数中就用到了不定长参数。
a = 1
b = 23
c = 40
d = False
print(a,b,c,d)
print 函数到底能传递几个参数?其实没有限制,想传多少参数都可以,这就是不定长参数。不定长参数有两种形式:*args 和 **kwargs 。
格式:
def num_sum(a,b,*args) * 一定要,args可以修改成别的,但不建议修改。
- 默认以元组的形式接收传递的值
- 放在形参后面
- 可以不传值
- 当传入单个值的时候使用
格式一:
def num_sum(*args):
x= 0
for i in args:
x += i
return x
# 调用函数
x = num_sum(1,12,13,14) # 由于没有形参,参数全部传给agrs
print(x)
格式二:
def sum_sef(x,*args):
res = 0
for num in args:
y+=num
return res
res = sum_sef(1,2,3,4,5) #形参x接受了1,剩下的实参没有形参接受
print(res)
**kwargs
格式:
def dem(a,b,**kwargs) **一定要,kwargs关键字可以修改成别的,但不建议修。
- 不定长参数**kwargs将传入的参数以字典格式封装。
- **kwargs 放置 *args后面,顺序不能颠倒。
- 如果没有为函数传递不定长参数,默认为空字典。
def test(a,b,*args,**kwargs):
print(a)
print(b)
print(kwargs)
#调用函数
test(1,2,name="小刘",age=18,sex="男")
"""
输出结果
1
2
{'name': '小刘', 'age': 18, 'sex': '男'}
"""
自动拆包
防止在调用函数的时候,误调用不定长参数。
def test(a,b,*args,**kwargs):
print(a)
print(b)
print(args)
print(kwargs)
A = (1,2,3)
B = {"name":"laowang"}
# a,b分别都被当成一个元素传入*args
test(11,22,A,B)
"""
输出结果:
11
22
((1, 2, 3), {'name': 'laowang'})
{}
"""
# 这里会自动拆包,将元组和字典拆分成单个元素和键值对
test(11,22,*A,**B)
"""
输出结果:
11
22
(1, 2, 3)
{'name': 'laowang'}
"""
函数的递归(重点)
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数,若无结束条件,程序会造成内存溢出。
- 必须设置一个明确的结束条件;
- 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
- 相邻两次重复之间有紧密的联系,前一次要为后一次做准备(通常前一次的输出就作为后一次的输入)。
# 定义一个5的阶乘 5!
# 常规写法
def num():
i = 1
res = 1
while i <= 5:
res *= i
i += 1
return res
print("常规写法", num())
# 递归写法
def sum1(i):
if i <= 1:
return 1 # 结束出口
else:
return i * sum1(i-1) # 反复调用函数
print("递归结果", sum1(5))
匿名函数 lambda
匿名函数的定义
- 使用lambda在某些时候然后代码更容易理解
- 使用Python写一些脚本时,使用lambda可以省去定义函数的过程,让代码更加精简。
- 对于一些抽象的,不会被别的地方再重复使用的函数,有时候函数起个名字也是个难题,使用lambda不需要考虑命名的问题
格式:
name = lambda [list]:表达式
定义 lambda 表达式,必须使用 lambda 关键字;[list] 作为可选参数,等同于定义函数是指定的参数列表;value 为该表达式的名称。
匿名函数的使用# 俩数字求和
# 传统写法
def num_sum(num1,num2):
sum = num1+num2
return print(sum)
# 调用函数
num_sum(1,1)
# 匿名函数
num_sum = lambda x,y:x+y
print(num_sum(1,1))
匿名函数和普通函数对比之下,匿名函数的使用能让代码更加简洁,当然匿名函数使用场景适用于比较简单的需求,对于复杂的计算,匿名函数是无法完成的;
# 使用匿名函数,将传入的函数按照空格拆分,拆分完后的字符串拼接成一个完整的字符串。
a = "涉江采芙蓉 兰泽多芳草 采之欲遗谁 所思在远道 "
print((lambda a:"".join(a.split(" ")))(a)) # 定义后将整个匿名函当个整体,传入参数。
lambda函数的当作参数的使用
# 定义两个数求和
def sum(a,b):
c = a+b
return print(c)
# 定义匿名函数
res = lambda d: d * 10
# 匿名函数当作参数传递
sum(2, res(2))
"""
输出结果:
22
"""
使用匿名函数对列表排序
# 使用匿名函数对列表
test_list0 = [1,43,566,786,34,64,4,345]
# 列表排序
test_list0.sort()
print(test_list0)
# 匿名函数
list_01 = (lambda test_list0:test_list0.sort())(test_list0)
print(list_01)
使用匿名函数对字典的排列
# 通过key排序
test_list = [{"name":"老王","age":"10"},{"name":"老李","age":"25"},{"name":"二狗","age":"33"}]
test_list.sort(key = lambda x:x["age"])
print(test_list)
sortde ( ) 函数
sorted() 函数对所有可迭代的对象进行排序 *** 作。
sort 与 sorted 区别:
sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序 *** 作。
list 的 sort 方法返回的是对已经存在的列表进行 *** 作,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的 *** 作。
- iterable -可迭代对象。
- cmp -比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。
- key -主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
- reverse -排序规则,reverse = True 降序 , reverse = False 升序(默认)。
# 在sortde函数中对参数key的使用
# 定义一个字典
dict_01 = {'a': 14, 'g': 20, 'c': 10, 'f': 99, 'e': 11}
# 升序 , []中为1对value进行排列,0对key进行排列
a = sorted(dict_01.items(),
key=lambda item: item[1], reverse=False)
print(a)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)