您当前的位置: 首页 >  Python

高校俱乐部

暂无认证

  • 1浏览

    0关注

    674博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Python匿名函数详解

高校俱乐部 发布时间:2014-10-15 17:22:14 ,浏览量:1

文章导读: 以前自己一直没搞明白Python中的匿名函数,现在拿这个问题基本上搞明白了,拿自己的理解整成一篇文章,附带大量例子,让其更加好理解。 在编程语言中,函数的应用: 1. 代码块重复,这时候必须考虑用到函数,降低程序的冗余度 2. 代码块复杂,这时候可以考虑用到函数,降低程序的可读性 在Python, 有两种函数, 一种是def 定义, 一种是lambda 函数 # 假如要求两个数之和,用普通函数或匿名函数如下: 1. def func(x,y):return x+y 2. lambda x,y: x+y 在编程语言中,C/C++/Java 属于过程式编程,而匿名函数(lambda) 一般应用于函数式编程中,举个简单例子也许比较好理解,对于一个列表,要求大于3的元素. 过程式编程实现: 也就是常规的方法 >>> L1 = [1,2,3,4,5] >>> L2 = [] >>> for i in L1: if i>3: L2.append(i) >>> L2 [4, 5] 函数式编程实现: 运用filter, 给其一个判断条件即可 >>> def func(x): return x>3 # 在函数中 >>> filter(func,[1,2,3,4,5]) [4, 5] 如果运用匿名函数,则更加精简,一行就可以了: >>> filter(lambda x:x>3,[1,2,3,4,5]) [4, 5] 总结: 从中可以看出,lambda 一般应用于函数式编程,代码简洁,常和reduce,filter 等函数结合使用。 格式如下: 解构上面的例子 x 为lambda 函数的一个参数 : 分割符 x>3 则是返回值,在lambda 函数中不能有return, 其实:后面就是返回值 为什么要用匿名函数? 1. 程序一次行使用,所以不需要定义函数名,节省内存中变量定义空间 2. 如果想让程序更加简洁时。 匿名函数几个规则: 1. 一般也就一行表达式,必须有返回值 2. 不能有return 3. 可以没有参数,可以有一个或多个参数 >>> def func(x): x+y >>> func >>> lambda x: x+y 无参匿名函数: ------ >>> t = lambda : True #分号前无任何参数 >>> t() True 等价于下面的def定义的函数 >>> def func(): return True >>> func() True ------ >>> s = "this is\na\ttest" #建此字符串按照正常情形输出 >>> s 'this is\na\ttest' >>> print s.split() #split函数默认分割:空格,换行符,TAB ['this', 'is', 'a', 'test'] >>> ' '.join(s.split()) #用join函数转一个列表为字符串 'this is a test' 等价于 >>> (lambda s:' '.join(s.split()))("this is\na\ttest") 带参数匿名函数 >>> lambda x: x**3 #一个参数 >>> lambda x,y,z:x+y+z #多个参数 >>> lambda x,y=3: x*y #允许参数存在默认值 匿名函数调用 #直接赋值给一个变量,然后再像一般函数调用 ------ >>> c = lambda x,y,z: x*y*z >>> c(2,3,4) 24 ------ >>> c = lambda x,y=2: x+y #使用了默认值 >>> c(10) #不输的话,使用默认值2 12 ------ >>> a = lambda *z:z #*z返回的是一个元祖 >>> a('Testing1','Testing2') ('Testing1', 'Testing2') ------ >>> c = lambda **Arg: Arg #arg返回的是一个字典 >>> c() {} #直接后面传递实参 ------ >>> (lambda x,y: x if x> y else y)(101,102) 102 ------ >>> (lambda x:x**2)(3) 9 #lambda返回的值,结合map,filter,reduce使用 >>> filter(lambda x:x%3==0,[1,2,3,4,5,6]) [3, 6] 等价于下面的列表推导式 >>> l = [x for x in [1,2,3,4,5,6] if x%3==0] >>> l [3, 6] 嵌套使用 #lambda嵌套到普通函数中,lambda函数本身做为return的值 ------ >>> def increment(n): ... return lambda x: x+n ... >>> f=increment(4) >>> f(2) 6 ------ >>> def say(): ... title = 'Sir,' ... action= lambda x: title + x ... return action ... >>> act = say() >>> act('Smith!') 'Sir,Smith!' 大量例子: 例01: 字符串联合,有默认值,也可以x=(lambda...)这种格式 >>> x = (lambda x="Boo",y="Too",z="Zoo": x+y+z) >>> x("Foo") 'FooTooZoo' 例02: 和列表联合使用 >>> L = [lambda x:x**2,\ lambda x:x**3,\ lambda x:x**4] >>> for f in L: ... print f(2) ... 4 8 16 也可以如下面这样调用 >>> print L[0](3) 9 例03: 和字典结合使用 >>> key = 'B' >>> dic = { 'A': lambda: 2*2,\ ... 'B': lambda: 2*4,\ ... 'C': lambda: 2*8} >>> dic[key]() 8 例04: 求最小值 >>> lower = lambda x,y: x if x>> lower('aa','ab') 'aa' 例05: 和map及list联合使用 >>> import sys >>> showall = lambda x:list(map(sys.stdout.write,x)) >>> showall(['Jerry\n','Sherry\n','Alice\n']) Jerry Sherry Alice >>> showall(['Jerry','Sherry','Alice']) JerrySherryAlice 等价于下面 >>> showall = lambda x: [sys.stdout.write(line) for line in x] >>> showall(('I\t','Love\t','You!')) I Love You![None, None, None] 例06: 在Tkinter中定义内联的callback函数 import sys from Tkinter import Button,mainloop x = Button(text='Press me', command=(lambda:sys.stdout.write('Hello,World\n'))) x.pack() x.mainloop() >>> Hello,World! Hello,World! 例07: lambda和map联合使用, >>> out = lambda *x: sys.stdout.write(' '.join(map(str,x))) >>> out('This','is','a','book!\n') This is a book! 例08: 判断字符串是否以某个字母开头 >>> print (lambda x: x.startswith('B'))('Bob') True ----- >>> Names = ['Anne', 'Amy', 'Bob', 'David', 'Carrie', 'Barbara', 'Zach'] >>> B_Name= filter(lambda x: x.startswith('B'),Names) >>> B_Name ['Bob', 'Barbara'] 例09: lambda和map联合使用: >>> squares = map(lambda x:x**2,range(5)) >>> squares [0, 1, 4, 9, 16] 例10. lambda和map,filter联合使用: >>> squares = map(lambda x:x**2,range(10)) >>> filters = filter(lambda x:x>5 and x>> filters [9, 16, 25, 36, 49] 例11. lambda和sorted联合使用 #按death名单里面,按年龄来排序 #匿名函数的值返回给key,进来排序 >>> death = [ ('James',32), ('Alies',20), ('Wendy',25)] >>> sorted(death,key=lambda age:age[1]) #按照第二个元素,索引为1排序 [('Alies', 20), ('Wendy', 25), ('James', 32)] 例12. lambda和reduce联合使用 >>> L = [1,2,3,4] >>> sum = reduce(lambda x,y:x+y,L) >>> sum 10 例13. 求2-50之间的素数 #素数:只能被1或被自己整除的数 >>> nums = range(2,50) >>> for i in nums: nums = filter(lambda x:x==i or x % i,nums) >>> nums [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47] 例14. 求两个列表元素的和 >>> a = [1,2,3,4] >>> b = [5,6,7,8] >>> map(lambda x,y:x+y, a,b) [6, 8, 10, 12] 例15. 求字符串每个单词的长度 >>> sentence = "Welcome To Beijing!" >>> words = sentence.split() >>> lengths = map(lambda x:len(x),words) >>> lengths [7, 2, 8] 写成一行: >>> print map(lambda x:len(x),'Welcome To Beijing!'.split()) 例16. 统计Linux系统挂载点 [root@host ~]# mount -v /dev/mapper/rootVG-root on / type ext3 (rw) proc on /proc type proc (rw) sysfs on /sys type sysfs (rw) devpts on /dev/pts type devpts (rw,gid=5,mode=620) /dev/mapper/rootVG-tmp on /tmp type ext3 (rw) /dev/mapper/rootVG-var on /var type ext3 (rw) /dev/cciss/c0d0p1 on /boot type ext3 (rw) tmpfs on /dev/shm type tmpfs (rw,size=90%) >>> import commands >>> mount = commands.getoutput('mount -v') >>> lines = mount.splitlines() >>> point = map(lambda line:line.split()[2],lines) >>> print point ['/', '/proc', '/sys', '/dev/pts', '/tmp', '/var'] 写成一行: >>> print map(lambda x:x.split()[2],commands.getoutput('mount -v').splitlines()) 效率问题: #比较def函数和lambda函数效率问题 输出结果: 1413272496.27 1413272703.05 (Def 函数:207s) 1413272904.49 (Lambda函数:201s) 从上面可以看出,两者的所需的时间差不多,效率丝毫不受影响. 难点例子: 参考链接:http://segmentfault.com/q/1010000000131575
关注
打赏
1656064541
查看更多评论
立即登录/注册

微信扫码登录

0.0375s