10. 匿名函数
(1)匿名函数简介
匿名函数:为了解决那些功能很简单的需求而设计的 “一句话函数”
Python匿名函数详解:https://blog.csdn.net/csdnstudent/article/details/40112803
https://www.cnblogs.com/bigtreei/p/7819594.html
https://www.cnblogs.com/xisheng/p/7301245.html
1 #初始代码 2 def calc(n): 3 return n**n 4 print(calc(10)) 5 6 #换成匿名函数 7 calc = lambda n:n**n 8 print(calc(10))
上图是对calc这个匿名函数的分
# 关于匿名函数格式的说明 函数名 = lambda 参数 :返回值(相当于函数体) # 参数可以有多个,用逗号隔开 # 匿名函数不管逻辑多复杂,只能写一行,且逻辑执行结束后的内容就是返回值 # 返回值和正常的函数一样可以是任意数据类型
由此可见:
匿名函数并不是真的没有名字。
匿名函数的调用和正常的调用也没有什么分别。
(2)匿名函数练习
# 把以下函数变成匿名函数 def add(x,y): return x+y # 匿名函数 add = lambda x,y : x+y
a.匿名函数与 max 混用
1 l=[3,2,100,999,213,1111,31121,333] 2 print(max(l)) 3 4 dic={'k1':10,'k2':100,'k3':30} 5 6 7 print(max(dic)) 8 print(dic[max(dic,key=lambda k:dic[k])])
输出:
31121
k3
100
b.匿名函数与 map 混用
1 res = map(lambda x:x**2,[1,5,7,4,8]) 2 for i in res: 3 print(i)
输出:
1 25 49 16 64
c.匿名函数与 filter 混用
1 res = filter(lambda x:x>10,[5,8,11,9,15]) 2 for i in res: 3 print(i)
输出:
11 15
11.函数式编程
函数是Python内建支持的一种封装,我们通过把大段代码拆成函数,通过一层一层的函数调用,就可以把复杂任务分解成简单的任务,这种分解可以称之为面向过程
函数式编程:
而函数式编程(请注意多了一个“式”字)——Functional Programming,虽然也可以归结到面向过程的程序设计,但其思想更接近数学计算。
我们首先要搞明白计算机(Computer)和计算(Compute)的概念。
在计算机的层次上,CPU执行的是加减乘除的指令代码,以及各种条件判断和跳转指令,所以,汇编语言是最贴近计算机的语言。
而计算则指数学意义上的计算,越是抽象的计算,离计算机硬件越远。
对应到编程语言,就是越低级的语言,越贴近计算机,抽象程度低,执行效率高,比如C语言;越高级的语言,越贴近计算,抽象程度高,执行效率低,比如Lisp语言。
函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量,因此,任意一个函数,只要输入是确定的,输出就是确定的,这种纯函数我们称之为没有副作用。而允许使用变量的程序设计语言,由于函数内部的变量状态不确定,同样的输入,可能得到不同的输出,因此,这种函数是有副作用的。
函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
Python对函数式编程提供部分支持。由于Python允许使用变量,因此,Python不是纯函数式编程语言。
1. 高阶函数
满足俩个特性任意一个即为高阶函数
1函数的传入参数是一个函数名
2函数的返回值是一个函数名
(1)高阶函数
a.map函数
1 array=[1,3,4,71,2] 2 3 ret=[] 4 for i in array: 5 ret.append(i**2) 6 print(ret) 7 8 #如果我们有一万个列表,那么你只能把上面的逻辑定义成函数 9 def map_test(array): 10 ret=[] 11 for i in array: 12 ret.append(i**2) 13 return ret 14 15 print(map_test(array)) 16 17 #如果我们的需求变了,不是把列表中每个元素都平方,还有加1,减一,那么可以这样 18 def add_num(x): 19 return x+1 20 def map_test(func,array): 21 ret=[] 22 for i in array: 23 ret.append(func(i)) 24 return ret 25 26 print(map_test(add_num,array)) 27 #可以使用匿名函数 28 print(map_test(lambda x:x-1,array)) 29 30 31 #上面就是map函数的功能,map得到的结果是可迭代对象 32 print(map(lambda x:x-1,range(5)))
b.reduce函数
1 from functools import reduce 2 #合并,得一个合并的结果 3 array_test=[1,2,3,4,5,6,7] 4 array=range(100) 5 6 #报错啊,res没有指定初始值 7 def reduce_test(func,array): 8 l=list(array) 9 for i in l: 10 res=func(res,i) 11 return res 12 13 # print(reduce_test(lambda x,y:x+y,array)) 14 15 #可以从列表左边弹出第一个值 16 def reduce_test(func,array): 17 l=list(array) 18 res=l.pop(0) 19 for i in l: 20 res=func(res,i) 21 return res 22 23 print(reduce_test(lambda x,y:x+y,array)) 24 25 #我们应该支持用户自己传入初始值 26 def reduce_test(func,array,init=None): 27 l=list(array) 28 if init is None: 29 res=l.pop(0) 30 else: 31 res=init 32 for i in l: 33 res=func(res,i) 34 return res 35 36 print(reduce_test(lambda x,y:x+y,array)) 37 print(reduce_test(lambda x,y:x+y,array,50))
c.filter函数(filter函数)
1 #电影院聚集了一群看电影bb的傻逼,让我们找出他们 2 movie_people=['alex','wupeiqi','yuanhao','sb_alex','sb_wupeiqi','sb_yuanhao'] 3 4 def tell_sb(x): 5 return x.startswith('sb') 6 7 8 def filter_test(func,array): 9 ret=[] 10 for i in array: 11 if func(i): 12 ret.append(i) 13 return ret 14 15 print(filter_test(tell_sb,movie_people)) 16 17 18 #函数filter,返回可迭代对象 19 print(filter(lambda x:x.startswith('sb'),movie_people))
d.总结
1 #当然了,map,filter,reduce,可以处理所有数据类型 2 3 name_dic=[ 4 {'name':'alex','age':1000}, 5 {'name':'wupeiqi','age':10000}, 6 {'name':'yuanhao','age':9000}, 7 {'name':'linhaifeng','age':18}, 8 ] 9 #利用filter过滤掉千年王八,万年龟,还有一个九千岁 10 def func(x): 11 age_list=[1000,10000,9000] 12 return x['age'] not in age_list 13 14 15 res=filter(func,name_dic) 16 for i in res: 17 print(i) 18 19 res=filter(lambda x:x['age'] == 18,name_dic) 20 for i in res: 21 print(i) 22 23 24 #reduce用来计算1到100的和 25 from functools import reduce 26 print(reduce(lambda x,y:x+y,range(100),100)) 27 print(reduce(lambda x,y:x+y,range(1,101))) 28 29 #用map来处理字符串列表啊,把列表中所有人都变成sb,比方alex_sb 30 name=['alex','wupeiqi','yuanhao'] 31 32 res=map(lambda x:x+'_sb',name) 33 for i in res: 34 print(i)
12.内置函数
1 字典的运算:最小值,最大值,排序 2 salaries={ 3 'egon':3000, 4 'alex':100000000, 5 'wupeiqi':10000, 6 'yuanhao':2000 7 } 8 9 迭代字典,取得是key,因而比较的是key的最大和最小值 10 >>> max(salaries) 11 'yuanhao' 12 >>> min(salaries) 13 'alex' 14 15 可以取values,来比较 16 >>> max(salaries.values()) 17 100000000 18 >>> min(salaries.values()) 19 2000 20 但通常我们都是想取出,工资最高的那个人名,即比较的是salaries的值,得到的是键 21 >>> max(salaries,key=lambda k:salary[k]) 22 'alex' 23 >>> min(salaries,key=lambda k:salary[k]) 24 'yuanhao' 25 26 27 28 也可以通过zip的方式实现 29 salaries_and_names=zip(salaries.values(),salaries.keys()) 30 31 先比较值,值相同则比较键 32 >>> max(salaries_and_names) 33 (100000000, 'alex') 34 35 36 salaries_and_names是迭代器,因而只能访问一次 37 >>> min(salaries_and_names) 38 Traceback (most recent call last): 39 File "<stdin>", line 1, in <module> 40 ValueError: min() arg is an empty sequence 41 42 43 44 sorted(iterable,key=None,reverse=False)
内置参数详解 https://docs.python.org/3/library/functions.html?highlight=built#ascii