• python--lambda和def函数


    1、Python lambda和Python def区别分析

    Python支持一种有趣的语法,它允许你快速定义单行的最小函数。这些叫做lambda的函数,是从Lisp借用来的,可以用在任何需要函数的地方。

    lambda的语法时常会使人感到困惑,lambda是什么,为什么要使用lambda,是不是必须使用lambda?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> def f(x):
    ...   return x+2
    ...
    >>> f(1)
    3
    >>> f = lambda x:x+2
    >>> f(1)
    3
    >>> (lambda x:x+2)(1)
    3

    Python def和Python lambda它们有相似点也有不同点。
    相似点: 这两个很重要的相似点就是都可以定义一些固定的方法或者是流程,供给程序来调用,比如上面例子中定义一个变量加2的方法。 输出的结果都是3,如果你要完成一些固定的流程的话,上面几种你都可以任意选择。

    上面是相同点,那么有那些不同点?
    它们的主要不同点是Python def是语句而Python lambda是表达式。lambda简化了函数定义的书写形式,使代码更为简洁。但是使用函数的定义方式更为直观,易理解。

    Python里面语句是可以嵌套的,比如你需要根据某个条件来定义方法,那只能用def。用lambda就会报错。

    1
    2
    3
    4
    5
    6
    >>> if a==1:
    ...   def info():
    ...     print '1'*5
    ... else:
    ...   def info2():
    ...     print 'info2'

    而有的时候你需要在python表达式里操作的时候,那需要用到表达式嵌套,这个时候Python def就不能得到你想要的结果,那只能用Python lambda,如下例子:
    输出e字符串出现频率最高的字母:

    1
    2
    3
    4
    5
    6
    >>> str='www.linuxeye.com linuxeye.com'
    >>> L = ([(i,str.count(i)) for i in set(str)])
    [(' ', 1), ('c', 2), ('e', 4), ('i', 2), ('m', 2), ('l', 2), ('o', 2), ('n', 2), ('u', 2), ('w', 3), ('y', 2), ('x', 2), ('.', 3)]
    >>> L.sort(key = lambda k:k[1],reverse = True)
    >>> print L[0][0]
    e

    2、Python的lambda匿名函数

    (1)使用Python写一些执行脚本时,使用lambda可以省去定义函数的过程,让代码更加精简。

    (2)对于一些抽象的,不会别的地方再复用的函数,有时候给函数起个名字也是个难题,使用lambda不需要考虑命名的问题。

    (3)使用lambda在某些时候让代码更容易理解。

    lambda基础
    lambda语句中,冒号前是参数,可以有多个,用逗号隔开,冒号右边的返回值。lambda语句构建的其实是一个函数对象,代码如下:

    g = lambda x : x**2
    print g
    <function <lambda> at 0x00AFAAF0>

    C#3.0开始,也有了lambda表达式,省去了使用delegate的麻烦写法。C#中的lambda表达式关键字是=>,看下面的一个例子,代码如下:

    var array = new int[] {2, 3, 5, 7, 9};
    var result = array.Where(n => n > 3); // [5, 6, 9]

    C#使用了扩展方法,才使得数组对象拥有了像Where,Sum之类方便的方法。Python中,也有几个定义好的全局函数方便使用的,他们就是filter, map, reduce。代码如下:

    >>> foo = [2, 18, 9, 22, 17, 24, 8, 12, 27]
    >>>
    >>> print filter(lambda x: x % 3 == 0, foo)
    [18, 9, 24, 12, 27]
    >>>
    >>> print map(lambda x: x * 2 + 10, foo)
    [14, 46, 28, 54, 44, 58, 26, 34, 64]
    >>>
    >>> print reduce(lambda x, y: x + y, foo)
    139

    非lambda不可?
    上面例子中的map的作用,和C#的Where扩展方法一样,非常简单方便。但是,Python是否非要使用lambda才能做到这样的简洁程度呢?在对象遍历处理方面,其实Python的for..in..if语法已经很强大,并且在易读上胜过了lambda。比如上面map的例子,可以写成,代码如下:

    print [x * 2 + 10 for x in foo]

    非常的简洁,易懂。filter的例子可以写成,代码如下:

    print [x for x in foo if x % 3 == 0]

    同样也是比lambda的方式更容易理解。

    所以,什么时候使用lambda,什么时候不用,需要具体情况具体分析,只要表达的意图清晰就好。一般情况下,如果for..in..if能做的,我都不会选择lambda。

    lambda broken?
    在数学教学中,经常会使用到lambda,比如有一位老兄就遇到这样一个问题。他想创建一个函数数组fs=[f0,...,f9] where fi(n)=i+n. 于是乎,就定义了这么一个lambda函数,代码如下:

    fs = [(lambda n: i + n) for i in range(10)]

    但是,奇怪的是,代码如下:

    >>> fs[3](4)
    13
    >>> fs[4](4)
    13
    >>> fs[5](4)
    13

    结果并没有达到这位老兄的预期,预期的结果应该是,代码如下:

    >>> fs[3](4)
    7
    >>> fs[4](4)
    8
    >>> fs[5](4)
    9

    问题其实出在变量i上。上面的代码换个简单的不使用lambda的缩减版本,代码如下:

    i = 1
    def fs(n):
    return n + i
    print fs(1) # 2
    i = 2
    print fs(1) # 3

    可见,上面没有达到预期的原因是lambda中的i使用的是匿名函数外的全局变量。修改一下,代码如下:

    fs = [(lambda n, i=i : i + n) for i in range(10)]
    >>> fs[3](4)
    7
    >>> fs[4](4)
    8
    >>> fs[5](4)
    9

    3、Python def函数

    Python编程中对于某些需要重复调用的程序,可以使用函数进行定义,基本形式为:

    def 函数名(参数1, 参数2, ……, 参数N):

    执行语句函数名为调用的表示名,参数则是传入的参数,可以更具需要定义,也可以没有。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 例1:简单的函数使用
    # coding=gb2312
     
    # 定义函数
    def hello():
      print 'hello python!'
       
    # 调用函数   
    hello()
       
    >>> hello python!

    函数可以带参数和返回值,参数将按从左到右的匹配,参数可设置默认值,当使用函数时没给相应的参数时,会按照默认值进行赋值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # 例2:累加计算值
    # coding=gb2312
     
    # 定义函数
    def myadd(a=1,b=100):
      result = 0
      i = a
      while i <= b:  # 默认值为1+2+3+……+100
        result +=
        i += 1
      return result
     
    # 打印1+2+……+10   
    print myadd(1,10)
    print myadd()    # 使用默认参数1,100
    print myadd(50)   # a赋值50,b使用默认值
       
    >>> 55
    >>> 5050
    >>> 3825

    Python 函数的参数传递时,值得注意的是参数传入时若为变量会被当作临时赋值给参数变量,如果是对象则会被引用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # 例3:
    # coding=gb2312
     
    def testpara(p1,p2):
      p1 = 10
      p2.append('hello')
     
    l = []   # 定义一数组对像
    a = 20   # 给变量a赋值
    testpara(a,l) # 变量a与对象数组l作为参数传入
    print a   # 打印运行参数后的值
    for v in l: # 打印数组对象的成员
      print v
         
    >>> 20    # 调用函数后a变量并未被复值
    >>> hello  # 而对象l数组则增加成员hello
  • 相关阅读:
    当别人没说好,那么事就没达成协定
    设计模式(六):原型模式
    《一拳超人》观后感
    设计模式(五):中介者模式
    设计模式(四):单例模式与工厂模式
    设计模式(二):构造器模式与模块模式
    设计模式(一):概念小谈
    CSS代码记录
    java之如何实现调用启动一个可执行文件,exe
    file类之目录
  • 原文地址:https://www.cnblogs.com/chamie/p/4843707.html
Copyright © 2020-2023  润新知