一道面试题让我重新学了一遍匿名函数
回复“书籍”即可获赠Python从入门到进阶共10本电子书
前言
首先祝各位节日快乐,不管有没有npy,大家还是要快乐,过节也不能停止学习。上一篇文章群友问了道3行代码的python面试题,我懵逼了...给大家说了一道Python面试题,很多小伙伴都拍了自己大腿,我竟然这么无知。
不要慌,今天kuls带大家来学习学习匿名函数
。首先看这个名字就知道这个函数没有名字(禁止套娃),那它是个啥玩意?
匿名函数
大家不慌,其实匿名函数只有一行代码:
lambda argument1, argument2,... argumentN : expression
先直接给大家看一个小案例,我们再来解释是啥意思:
f = lambda a, b, c: a+b+c
print(f(6, 6, 6))
把上面的函数写成普通函数:
def f(a, b, c):
return a+b+c
print(f(6, 6, 6))
相信大家看到了它的普通函数就知道是啥意思了。我们看到上面的代码,在匿名函数中我们使用lambda
关键字来表示匿名函数。
冒号之前是我们的变量
,冒号之后是我们的表达式
。
大家可能发现我们lambda表达式中是没有return语句
的,因为lambda不需要它来返回,表达式本身结果就是返回值。
跟函数的区别
既然说lambda是属于表达式,那么它必定跟函数是有区别
的,举一个简单的例子:表达式可以在list中使用,而函数则不行。
[(lambda x:x**2)(x) for x in range(10)]
输出结果:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
有一部分小伙伴可能不太懂上面的for循环语句,我在这里给大家分析一下:
[(lambda x:x**2)(x) for x in range(10)]
这个lambda表达式在list中,这个不用多说,但是后面那个(x)是啥意思呢?我们首先把它去掉打印一下:
[(lambda x:x**2) for x in range(10)]
输出结果:
[<function . at 0x1014bbf80>, <function . at 0x10146dcb0>, <function . at 0x101465dd0>, <function . at 0x1014b3dd0>, <function . at 0x1014b3c20>, <function . at 0x1014b3d40>, <function . at 0x1014b3b90>, <function . at 0x1014b3b00>, <function . at 0x1014b3cb0>, <function . at 0x1014818c0>]
我们可以看到返回的是函数地址,这里也就说明此时的列表中存储的只是内存地址,并没有真正的调用lambda函数进行计算。这样也就说明了(x)的作用就是类似于函数中的参数,将for循环中的x值传给lambda表达式,然后进行计算。
除此之外,lambda表达式还能作为函数的参数,这里我就不去展示了。
一些有意思的匿名函数
这里的一些匿名函数,我也是从网上摘取过来的,大家可以看看这些匿名函数。
无参匿名函数:
t = lambda : True #分号前无任何参数
t()
True
等价于下面的def定义的函数
def func(): return True
func()
True
参数存在默认值
f2 = lambda x,y=3: x*y
print(f2(2))
结果:
6
表达式后传参
(lambda x,y: x if x> y else y)(103,102)
输出:
103
由于篇幅原因这里就举几个这样的例子,需要看更多有意思的匿名函数,大家可以自行百度。
匿名函数的好处
我们接触了匿名函数,并且知道它的基本使用。那这玩意到底有啥用?
其实大家能够很直观的就能够看到,使用匿名函数减少了我们的代码量
,大家不要忽略这一点,认为它并没有给我们省很多的代码量,当你做的项目足够大时,你会恨不得少一个字母。
函数式编程
说到了lambda表达式,我们不得不提Python的函数式编程。什么是函数式编程?指代码中每一块都是不可变的,都由纯函数的形式组成。这里的纯函数,是指函数本身相互独立、互不影响,对于相同的输入,总会有相同的输出,没有任何副作用。
大家可能还是不太理解什么是函数式编程,到底啥不能改变,我们举个简单的例子:
l = [1,2,3]
def a(l):
for i in range(0,len(l)):
l[i] += 10
return l
print(a(l))
大家可以看到,上面我们将列表l中的值全部加10,这样列表中的值发生了改变,也就是说我们函数里面发生了变化,所以我们不能称之为纯函数。那么纯函数的形式怎么写呢?
def b(l):
new_l = []
for item in l:
new_l.append(item+10)
return new_l
print(b(l))
我们需要在里面重新创建一个新的list。
为什么要说函数式编程呢?因为在python中提供了几个函数来支持函数式编程:
map(function, iterable)
r = map(lambda x:x**2,[1,2,3])
list(r)
结果:
[1, 4, 9]
map函数式python自带的函数,map()传入的第一个参数是f,即函数对象本身。由于结果r是一个Iterator,Iterator是惰性序列,因此通过list()函数让它把整个序列都计算出来并返回一个list。
fliter(function, iterable)
其实它和上面的map非常的相似,同样是传入函数以及iterable。fliter函数会对iterable中的每一个元素进行function的判断,并且返回True或者Flase,最后会把True的元素组成一个列表返回。
>>> l = [1, 2, 3, 4, 5]
>>> new_list = filter(lambda x: x % 2 == 0, l)
>>> list(new_list)
结果:
[2, 4]
reduce(function, iterable)
reduce(function, iterable)表示对某个集合做function函数的累积。
直接给大家看下代码
>>> from functools import reduce
>>> l = [1,2,3]
>>> r = reduce(lambda x,y :x*y,l)
>>> print(r)
结果:
6
总结
总算写完了,虽然匿名函数在平常的开发中比较少见,但是它是一个开发人员必不可少的知识。从之前的面试题我们也可以看到,匿名函数的考察也是会有的。文章纯手敲,如果里面有错误,还麻烦联系我微信(下面有二维码)。
原创不易,希望大家多多点再看!在看数
超过30,马上出下一篇干货文!!!
本文部分知识参考了:
https://blog.csdn.net/weixin_34007291/article/details/88755406
------------------- End -------------------
往期精彩文章推荐:
如何利用Scrapy爬虫框架抓取网页全部文章信息(中篇)
如何利用Scrapy爬虫框架抓取网页全部文章信息(上篇)
关于Scrapy爬虫框架中meta参数的使用示例演示(上)
关于Scrapy爬虫框架中meta参数的使用示例演示(下)
欢迎大家点赞,留言,转发,转载,感谢大家的相伴与支持
想加入Python学习群请在后台回复【入群】
万水千山总是情,点个【在看】行不行
/今日留言主题/
随便说一两句吧~~