一、函数的高级用法
1.1 函数可以被引用(可以赋值)
def fn():
print("我是fn")
f = fn
print(f,fn) # <function fn at 0x00000285399F73A0> <function fn at 0x00000285399F73A0>
f() # 我是fn
1.2函数可以作为参数传入另一个函数
def fn():
print("我是fn")
def fn2(x): # x——》fn
print(x) # <function fn at 0x000002AAB84573A0>
x() # 我是fn
fn2(fn)
1.3 可以将函数作为返回值
def fn():
print("我是fn")
def fn2(x): # x——》fn
return x
x = fn2(fn) # fn
x() # 我是fn
1.4.函数可以作为容器的元素
def fn():
print("我是fn")
list1 = [1,2,3,fn]
f = list1[3] # fn
f()
二、 匿名函数(lambda)
语法: lambda 参数列表:运算表达式# 普通写法 def fn(x): return x*x print(fn(5)) # lambda写法 f = lambda x:x*x print(f(5)) # 25
总结: 1.lambda并不会带来程序运行效率的提高,只会使代码更加简洁 2.如果使用 lambda,lambda内部不要有循环,因为可读性不好,有的话请使用标准函数来完成,目的使为了代码有可重用性和可读性 3.lambda只是为了减少单行函数的定义而存在,如果一个函数,只有一个返回值,只有一句代码,就可以使用 lambda
三、 高阶函数
3.1 高阶内置函数简介
高阶函数其实就是把函数作为参数传入abs() # 绝对值 print(abs(-1)) # 1 sum() print(sum([1, 2, 3, 4, 5])) # 15 print(sum((2, 3, 4), 2)) # 元组计算总和后再加 2 得到结果是11 print(sum([2, 3, 4, 1], 1)) # 列表计算总和后再加 1 得到结果是11 round() # 四舍五入,精度问题 四舍六入 print(round(4.3)) 4 print(round(4.8)) 5
sum() ==》 求和函数
round() ==》 四舍五入(理论上是四舍五入,但小数为5的时候精度有问题)
任意两个数字,对两个数字求绝对值后进行求和
def ab_sum(a,b,f): return f(a)+f(b) res = ab_sum(-1,-4,abs) #把abs作为参数传入到函数里面,传的是函数本身不是传函数调用 print(res) def xfs(x): return -x def ab_sum(a,b,f): # f是一个函数参数 return f(a)+f(b) res = ab_sum(-1,-4,xfs) # 求的是相反数的和 print(res)
3.2函数三剑客:map , reduce, filter
3.2.1 map()
map(func,seq) 第一个参数是给一个函数,第二个参数是给一个序列类型,map返回的是一个迭代器将列表序列中各个元素加一# 普通写法 list1 = [1,2,3,4,5] list2 = [] for i in list1: list2.append(i+1) print(list2) # [2, 3, 4, 5, 6] # map写法 list1 = [1,2,3,4,5] def add1(x): return x+1 print(list(map(add1,list1))) # [2, 3, 4, 5, 6]
迭代器就是可以用来循环迭代取值 list可以一次性拿到迭代器所有元素并且放到数组中list1 = [-1,2,-3,4,-5] print(list(map(abs,list1))) # [1, 2, 3, 4, 5] list1 = [1,2,3,4,5] def add1(x): return '星奕' print(list(map(add1,list1))) # ['星奕', '星奕', '星奕', '星奕', '星奕'] # lambda写法 list1 = [1,2,3,4,5] print(list(map(lambda x: x + 1, list1)))
总结: 1.map内置函数的作用就是操作序列中所有的元素,并返回一个迭代器,迭代器转为列表 2.咱们的lambda表达式可以专门配合我们的高阶内置函数来做简单实现
3.2.2 reduce()
reduce(func,seq)将每次函数计算的结果继续和序列的下一个元素做累积计算,最终结果只有一个值注意:reduce传入的参数func必须接受两个参数
list1 = [1,2,3,4,5] sum = 0 for i in list1: sum += i print(sum) #15 from functools import reduce # 导包,后续会介绍 list1 = [1,2,3,4,5] def f(a,b): #print('进入f') #print('a=',a) #print('b=',b) return a+b res = reduce(f,list1) print(res) # 15
3.2.3 filter()
语法: filter(func,seq)第一个参数是给一个函数,第二个参数给一个序列类型,用于过滤序列,过滤掉不符合条件的元素,结果可以通过list转换保留一个序列中所有的偶数# 普通写法 list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] for i in list1: if i % 2 != 0: list1.remove(i) print(list1) # filter写法 list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] def o2s(x): return x % 2 == 0 print(list(filter(o2s, list1))) # lambda写法 list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] print(list(filter(lambda x: x % 2 == 0, list1)))
3.2.4 sorted
sorted(序列类型,key=函数) 返回一个排序后的序列list1 = [2,4,1,3,5,6,9,7] print(sorted(list1)) # 升序 [1, 2, 3, 4, 5, 6, 7, 9] print(sorted(list1,reverse=True)) # 降序 [9, 7, 6, 5, 4, 3, 2, 1]
# 根据列表中的分数进行排序# 普通写法 list1 = ["小奕:69","小琪:79","大力:89","小鑫:100","小川:59"] def f(x): arr = x.split(":") return int(arr[1]) print(sorted(list1, key=f)) # lambda写法 list1 = ["小奕:69","小琪:79","大力:89","小鑫:100","小川:59"] print(sorted(list1, key=lambda x: int(x.split(":")[1])))
max(可迭代对象,key=函数):根据函数获取可迭代对象的最大值 min(可迭代对象,key=函数):根据函数获取可迭代对象的最小值a = ["张三:100","李四:77","王五:99","赵六:50"] def f(x): return int(x.split(":")[1]) print(min(a,key=f)) # 赵六:50 print(max(a,key=f)) # 张三:100
总结: 有了这些内置高阶函数,我们可以更加灵活的去操作序列类型,比原始的for循环 if判断 要简单那么一点,但是其实也就简单一点点,更多是变灵活了
四、递归函数
如果一个函数的内部调用了自己,就叫递归
1.如果要定义递归函数,不想让他报错的话,必须要有出口
2.不断的向出口接近
打印1到500
# 例1: x = 1 def func(): global x if x == 500: print(x) else: print(x) x += 1 return func() func()
# 例2 def func(1): if x == 501: return print(x) return func(x+1) func(1)
9! = 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 (9的阶乘)
def f(n): if n == 1: return True return n*f(n-1) a = f(9) print(a)