1. 函数定义
# 函数定义:实现某功能代码封装,较少冗余的代码块
2. 函数参数
2.1 形式参数
2.1.1 定义
# 函数定义时的函数参数名称称为形式参数
2.1.2 分类
# 必选参数
def info(name, age, sex): # name,age,sex为必选参数
# 默认参数
# 默认参数可以传递也可以不传递参数
# 规则:default argument follows non-default argument
def info(name, age, sex='male') # sex为默认参数,male为默认参数值;name,age为必选参数
# 可变长度位置参数
# *args
def myargs(*num): # *将输入的参数打包:1,2,3->打包为元组(1,2,3)
print(*num)
print(type(num), num) # 输出num类型和num
myargs() # <class 'tuple'> ()
print("\n")
myargs(1) # 1 <class 'tuple'> (1,)
print("\n")
myargs(1, 2) # 1 2 <class 'tuple'> (1, 2)
# 可变长度关键字参数
# **kwargs
def myargs(**num): # **将输入的参数打包成字典:a=1,b=2->{a:1,b:2}
print(num,type(num)) # 输出num及num类型
myargs(a=1, b=2) # {'a': 1, 'b': 2} <class 'dict'>
myargs(c=2, d=5, g=7) # {'c': 2, 'd': 5, 'g': 7} <class 'dict'>
2.2 实际参数
2.2.1 定义
函数调用时的提供的实际值称为实际参数
2.2.2 分类
# 位置参数
# 规则:info(sex='m', "sc", age=19)# 位置参数要位于关键字参数前面
# keyword argument follows positional argument
info('mghaolian', 18, 'men') # 'mghaolian', 18, 'men'为位置参数
# 关键字参数
info("sc", sex='m', age=19) # "sc"为位置参数, sex='m', age=19关键字参数
# 可变长度位置参数
def calculate_function(*args):
# sum1 = 0
# for i in args:
# sum1 += i
return sum(args) # 6
print(calculate_function(1,2,3))
# 可变长度关键字参数
def calculate_function(**myargs):
# sum1 = 0
# for i in myargs.values():
# sum1 += i
return sum(myargs.values())
print(calculate_function(a=1,b=2,c=3,d=9)) # 15
总结:无论形参还是实参,带等号的参数定义和传递都放在后面
3. 匿名函数
3.1 定义
# 不需要创建函数名,只能有一个函数,不用return
# 返回值就是该表达式结果
# lambda arg1,arg2:表达式
add = lambda x, y: x+y # 定义lambda函数,x y为参数,x+y为表达式,也是函数返回结果
print(add(2,3)) # 5
3.2 适用场景
# 匿名函数使用,当需要使用一个函数实现单一功能时,使用匿名函数简化代码,使代码简介优雅
lst = [1, 2, 3, 4, 5] # 定义列表
# map(function,iterable)
print(list(map(lambda x: x * x, lst))) # 使用map函数映射,并将map对象转化为列表输出,实现计算数字的乘方
def fun1(x): # 定义函数实现计算数字的平方
return x*x
print(list(map(fun1, lst)))
lst = [23.345,56.35456666,43.99998,43.345]
print(list(map(lambda x: round(x,2),lst))) # 利用lambda和map函数实现保留小数点后两位数
print(list(map(lambda x: '{:.2f}%'.format(x*100), lst))) #利用lambda和字符串的格式化实现百分数的转化并保留小数点后两位数
4. 递归函数
4.1 定义
# 函数Func(Type a,……)直接或间接调用函数本身,则该函数称为递归函数
4.2 实例
# 计算n!
def f(a):
if a == 1:
return 1 # 寻找递归函数的出口
return a*f(a-1)
print(f(4))
# 用递归实现斐波拉契数列 1,1,2,3,5,8,13
# 规律:f(n) = f(n-1) + f(n-2)
k = {1: 1, 2: 1}
def recursion(n):
if n in k:
return k[n] # 寻找递归函数的出口
else:
r = recursion(n - 1) + recursion(n - 2)
k[n] = r
return r
recursion(7)
print(list(map(lambda x: x, k.values())))
# 走楼梯问题 每次走楼梯都可以选择走一个台阶或者两个台阶
# n阶楼梯,一共几种走法
# n=1,1;
# n=2,2;
# n=3,3;
# n=4,5;
# n=10,几种走法?
def f(n):
if n==1: # 寻找递归函数的出口
return 1
elif n==2:
return 2 # 寻找递归函数的出口
else:
return f(n-1)+f(n-2)
print(f(10))
# 有一对雌雄兔子,每两个月就繁殖雌雄兔一对,问n月后有多少对兔子?
# 1,2--》1对
# 3,4--》2对
# 5,6--》4对
def f(n):
if n <= 2:
return 1 # 寻找递归函数的出口
return f(n-2)*2
print(f(19))
5. 函数返回值及函数的参数传递
5.1 return 关键字
# return标志语句块的结束,后面的代码不可以执行
# 定义函数,包含两个必选参数x y
def fun1(x, y):
print("return ......")
if x > y:
print("return x......")
return x # return返回结构该语句块结束
print("xxxx") # 位于return语句后面无法执行
print("return y......")
return y # return返回结构该语句块结束
print("return end......") # 位于return语句后面无法执行
# result = fun1(10,8)
# print(result)
i,j = fun1(100,8)
print(i,j)
print(fun1(100,8)) # return返回元组
5.2 参数传递
# 从动态类型的参数传递看,参数传递实际传递的是引用
# 不可变数据类型
def func1():
global x # 在声明全局之前不能使用,否则视为局部变量与全局变量声明矛盾
print(x, id(x)) # 1 2072128940336
x = 100
print(x, id(x)) # 100 2072129131984
x = 1
func1()
print(x, id(x)) # 100 2072129131984
def func1(x):
print(x, id(x)) # 1 2228869294384
x = 100
print(x, id(x)) # 100 2228869486032
x = 1
func1(x)
print(x, id(x)) # 1 2228869294384
# 可变数据类型的传递
# 在局部和全局都可以修改其值
# 参数定义时,尽量避免定义为可变数据类型 def f(a=[])
# 创建a只在函数定义时创建,再调用函数时只执行函数体里面的内容
def f(x):
x[0] = 100
print(x)
a = [1,2,3]
f(a) # [100, 2, 3]
print(a) # [100, 2, 3]
def f(a=[]):
a.append(1)
print(a)
f()
f()
f()
# 结果:
# [1]
# [1, 1]
# [1, 1, 1]