zoukankan      html  css  js  c++  java
  • Python匿名函数详解

    文章导读:

    转载自:https://blog.csdn.net/csdnstudent/article/details/40112803



    以前自己一直没搞明白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
    <function func at 0x0000000002F48DD8>
    >>> lambda x: x+y
    <function <lambda> at 0x0000000002F48D68>



    无参匿名函数:

    ------

    >>> t = lambda : True #分号前无任何参数
    >>> t()
    True

    等价于下面的def定义的函数
    >>> def func(): return True
    >>> func()
    True

    ------

    >>> s = "this is a test" #建此字符串按照正常情形输出
    >>> s
    'this is a test'
    >>> print s.split() #split函数默认分割:空格,换行符,TAB
    ['this', 'is', 'a', 'test']
    >>> ' '.join(s.split()) #用join函数转一个列表为字符串
    'this is a test'

    等价于

    >>> (lambda s:' '.join(s.split()))("this is a test")




    带参数匿名函数

    >>> 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<y else y
    >>> lower('aa','ab')
    'aa'



    例05: 和map及list联合使用

    >>> import sys
    >>> showall = lambda x:list(map(sys.stdout.write,x))
    >>> showall(['Jerry ','Sherry ','Alice '])
    Jerry
    Sherry
    Alice

    >>> showall(['Jerry','Sherry','Alice'])
    JerrySherryAlice

    等价于下面

    >>> showall = lambda x: [sys.stdout.write(line) for line in x]
    >>> showall(('I ','Love ','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 ')))
    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! ')
    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<50,squares)
    >>> 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

  • 相关阅读:
    107. Binary Tree Level Order Traversal II
    108. Convert Sorted Array to Binary Search Tree
    111. Minimum Depth of Binary Tree
    49. Group Anagrams
    使用MALTAB标定实践记录
    442. Find All Duplicates in an Array
    522. Longest Uncommon Subsequence II
    354. Russian Doll Envelopes
    opencv 小任务3 灰度直方图
    opencv 小任务2 灰度
  • 原文地址:https://www.cnblogs.com/aliceyang/p/12010317.html
Copyright © 2011-2022 走看看