上一个章节讲述了自定义函数,而匿名函数则是自定义函数中的特殊情况。
而其只需要一行就可以定义函数,并且还有一个炫酷的名字’lambda’
一、基础
lambda arg1,arg2,arg3,...argn:expression
def my_sum(num1, num2):
return num1+num2
mysum = lambda x,y: x+y
mysum(2,3)
- lambda表达式与正常函数的区别
- lambda是一个表达式,并不是一个语句
- 表达式:用一系列"公式"去表达一个东西,比如x + 2、x*2等等
- 语句:则一定是完成了某些功能,比如赋值语句x=1 完成了赋值,print语句打印,if 判断等
[(lambda x:x+2)(x) for x in range(5)]
l = [(1,2),(5,7),(3,4)]
l.sort(key = lambda x:x[1])
print(l)
二、为什么使用?
由上可以看出,一个程序完全可以在不使用lambda函数实现其所需要的功能。那我们使用它是为了什么呢?我们可以先大致分析下函数的作用:
第一点,如果程序的不同地方使用到了相同的代码,那么我们就可以把这部分代码提炼成一个函数,为它取个名字,这样我们就可以在不同地方通过这个函数的名字简单的去实现函数中定义的功能
第二点,如果某个功能的实现需要大量非重复的代码去实现,这些代码写在一起就会使程序的可读性异常的低,这个时候,我们就可以把这大量的代码分为多个函数去分别实现,再组装。
但是如果我们需要一个函数,它非常的简短,只需要一行就能完成;同时它在程序中只是别调用一次而已。那么这个时候我们再去使用def去定义一个函数嘛?
而这种情况下,我们的lambda表达式就会凸显出它的优势了!比如上诉的my_sum函数就是一个例子
三、python的函数式编程
函数式编程:指代码中每一块都是不可变的,都是由纯函数的形式组成。这个的纯函数,就是指函数本身相互独立、互不影响,对于相同的输入,总会有相同的输出,没有任何副作用。
l = [1,3,5,7]
def my_list(l):
for index in range(0,len(l)):
l[index] += 2
return l
print(f"第一次调用:{my_list(l)}")
print(f"第二次调用:{my_list(l)}")
l = [1,3,5,7]
def my_list(l):
my_arr = []
for index in range(0,len(l)):
my_arr.append(index)
return l
print(f"第一次调用:{my_list(l)}")
print(f"第二次调用:{my_list(l)}")
函数编程的优点:主要在于其纯函数和不可变的特性使得程序更加健壮,易于调试和测试;缺点就是限制多且难写,比如scala,不过python也并不是一门函数式的语言,但是其还是提供了一些函数式编程的特性,比如map()、filter()和reduce()这些函数,通常这会与lambda一起使用。 - map(func,iterable)函数,其表示对iterable中的每个元素都调用func函数,最后返回一个新的可遍历的集合
l = [1,2,3,4,5]
new_list = map(lambda x:x+1,l)
print(list(new_list))
四、一些性能测试:
python3 -mtimeit -s'xs=range(500000)' 'map(lambda x: x+1, xs)'
python3 -mtimeit -s'xs=range(500000)' '[x+1 for x in xs]'
python3 -mtimeit -s'xs=range(500000)' 'l = []' 'for i in xs: l.append(i+1)'
- filter(func,iterable)函数,其与参数那些与map类似,而其表示对iterable 中的每个元素,都使用func判断,并返回True或者False,最后将返回True的元素组成一个新的可遍历的集合
l = [1,2,3,4,5]
new_list = filter(lambda x:x+1,l)
- reduce(func,iterable)函数,它通常用来对一个集合做一些积累操作。func同样是一个函数对象,规定它有两个参数,表示对iterable 中的每个元素以及上一次调用后的结果,运用func进行计算,一直到最后返回一个单独的数值
from functools import reduce
l = [1,2,3,4,5]
list_sum = reduce(lambda x,y:x+y,l)
print(list_sum)
五、总结
你会发现上诉的函数式编程都可以用for循环或者list comprehension实现,那究竟该如何选择使用呢?经过上面的分析其实也可以得出,如果我们对集合元素的操作比较简单,数据量很大的情况下可以优先考虑lambda函数,如果我们数据量不大,元素操作复杂可以优先考虑for循环或者list comprehension实现去实现
|