• (二十)python 3 匿名函数


    匿名函数lambda

    Python使用lambda关键字创造匿名函数。所谓匿名,意即不再使用def语句这样标准的形式定义一个函数。这种语句的目的是由于性能的原因,在调用时绕过函数的栈分配。其语法是:

    lambda [arg1[, arg2, ... argN]]: expression

    其中,参数是可选的,如果使用参数的话,参数通常也会在表达式之中出现。

    无参数
    # 使用def定义函数的方法
    def true():
      return True
     
    #等价的lambda表达式
    >>> lambda :True
    <function <lambda> at 0x0000000001E42518>
     
    # 保留lambda对象到变量中,以便随时调用
    >>> true = lambda :True
    >>> true()
    True
    
    一个参数 
    # 使用def定义的函数
    def add( x, y ):
      return x + y
     
    # 使用lambda的表达式
    lambda x, y: x + y
     
    # lambda也允许有默认值和使用变长参数
    lambda x, y = 2: x + y
    lambda *z: z
     
    # 调用lambda函数
    >>> a = lambda x, y: x + y
    >>> a( 1, 3 )
    4
    >>> b = lambda x, y = 2: x + y
    >>> b( 1 )
    3
    >>> b( 1, 3 )
    4
    >>> c = lambda *z: z
    >>> c( 10, 'test')
    (10, 'test')
    

    lambda是单个的表达式,不是一个代码块 lambda的设计是为了满足简单函数的场景,仅能封装有限的逻辑,有复杂逻辑的情况有def来处理,所以lambda的功能要比def小的多  

    lambda表达式是可以嵌套的(闭包)

    >>> action = (lambda x : (lambda y : x + y))
    >>> a = action(10)
    >>> a(5)
    15
    

    匿名函数的使用  

    匿名函数通常被用作高阶函数(higher-order function,参数为函数的函数)的参数。比如,几个内置函数:filter(),map(),reduce()。下面我们分别看看这几个函数的用法及达到相同效果的python另一种特征的用法

    filter函数

    >>> list = [1, 2, 3]
    >>> result = filter(lambda x: x%2==0, list)
    >>> result
    [2]
    >>> result = [x for x in list if x%2==0]
    >>> result
    [2]
    

    map函数

    >>> result = map(lambda x: x*2, list)
    >>> result
    [2, 4, 6]
    >>> result = [x*2 for x in list]
    >>> result
    [2, 4, 6]
    

    reduce函数

    >>> result = reduce(lambda x, y: x+y,list)
    >>> result
    6
    >>> result = sum(list)
    >>> result
    6
    

    跳转表(jump table) 

    lambda的另一种用法是用来编写跳转表,也就是行为列表或字典,能按需执行特定的动作。

    >>> key = "get"
    >>> {"abc":(lambda : 2 + 2),"bcd" : (lambda : 3 + 3), "get" : (lambda : 4 + 4)}

    [key]() 8

      

    注意问题:

    x = 10
    a = lambda y: y + x
    
    x = 20 
    b = lambda y: y + x
    
    #猜想一下:a(10) 和 b(10)返回的结果是什么?如果你认为结果是20 和 30,那么就错了
    
    print(a(10))  ##输出:30
    
    print(b(10))  ##输出:30
    

    lambda表达式中的x是一个自由变量, 是在运行时绑定值,而不是定义时就绑定,即lambda表达式中的x是执行时的值,这与函数的默认值参数定义是不同的。例如:

    x = 15
    print(a(10))  ##输出:25
    
    
    x = 3
    print(a(10)) ##输出:13
    

    如果想让匿名函数,在定义时就捕获到参数值,可以将那个参数值定义成默认参数即可,例如:

    m = 4
    c = lambda n, m = m: m + n
    
    print(c(10))  ##输出:14
    
    m = 2
    print(c(10))  ##输出:14
    

      

    有时候,可能会不恰当的使用lambda表达式。 比如,通过在一个循环或列表推导中创建一个lambda表达式列表,并期望函数能在定义时就记住每次的迭代值。例如:

    funcs = [lambda x: x+n for n in range(3)]
    for f in funcs:
        print(f(0))
    
    
    # 2
    # 2
    # 2
    

    但是实际效果是,n的值为迭代的最后一个值。将参数值设置为默认参数,才能得到想要的效果,修改代码如下:

    funcs = [lambda x, n = n: x+n for n in range(3)]
    for f in funcs:
        print(f(0))
    
    
    # 0
    # 1
    # 2
    

      

  • 相关阅读:
    js 高阶函数之柯里化
    JavaScript 相关的工具代码
    JS 数组、对象的深拷贝
    页面性能优化
    axios(封装使用、拦截特定请求、判断所有请求加载完毕)
    java 实现登录验证码 (kaptcha 验证码组件)
    告别 hash 路由,迎接 history 路由
    解决 Vue 动态生成 el-checkbox 点击无法赋值问题
    分享基于 websocket 网页端聊天室
    vue + element 动态渲染、移除表单并添加验证
  • 原文地址:https://www.cnblogs.com/a-ant/p/11030145.html
Copyright © 2020-2023  润新知