• 对 a = [lambda : x for x in range(3)] 的理解


    • 上面的语句创建了一个列表 a ,其中有三个元素,每个元素都是一个 lambda 匿名函数。
    >>> a = [lambda : x for x in range(3)]
    >>> a
    [<function <listcomp>.<lambda> at 0x7f79c874ae18>, 
    <function <listcomp>.<lambda> at 0x7f79c874aea0>, 
    <function <listcomp>.<lambda> at 0x7f79c874af28>]
    >>> a[0]()
    2
    >>> a[1]()
    2
    >>> a[2]()
    2
    >>>
    
    • 可是为什么三个函数的返回值都为 2 呢?

    • 这是因为函数创建的时候,并没有传递参数,而只有当我们最后调用三个函数的时候,这时候 x 才被作为实参传递进 lambda 函数,而此时的 x = 2,所以三个函数的返回值都为 2。

    • 以下的例子就可以很清晰地说明这个问题。

    >>> a = []
    >>> for i in range(3):
    ...     a.append(lambda:i)
    ... 
    >>> a
    [<function <lambda> at 0x7f79c88022f0>, 
    <function <lambda> at 0x7f79c8802378>, 
    <function <lambda> at 0x7f79c8802400>]
    >>> a[0]()
    2
    >>> a[1]()
    2
    >>> a[2]()
    2
    >>> i
    2
    >>> i = 10
    >>> a[2]()
    10
    >>> 
    
    • Python 的 for 循环并不会引入新的作用域,因此当最后调用 lambda 函数的时候,实际上是把当前 i 的值 2 传递了进去,而当我们更改了 i 的值后,函数的返回值也就相应改变了。

    • 再看下面这个例子。

    >>> a = [lambda x=x : x for x in range(3)]
    >>> a[0]()
    0
    >>> a[1]()
    1
    >>> a[2]()
    2
    >>> a[2](10)
    10
    
    • 这次,在循环过程中,我们创建函数的时候把 x 的值作为默认参数传递了进去,因此输出就变成了 0, 1, 2,相当于使用了默认参数。

    • 而如果我们将列表替换成元组,a 就变成了一个生成器,看下面的例子。

    >>> a = (lambda:x for x in range(3))
    >>> a
    <generator object <genexpr> at 0x7f79c8f08200>
    >>> next(a)
    <function <genexpr>.<lambda> at 0x7f79ca827f28>
    >>> next(a)
    <function <genexpr>.<lambda> at 0x7f79c88022f0>
    >>> next(a)
    <function <genexpr>.<lambda> at 0x7f79ca827f28>
    >>> next(a)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    >>> a = (lambda:x for x in range(3))
    >>> next(a)()
    0
    >>> next(a)()
    1
    >>> next(a)()
    2
    >>> next(a)()
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    >>>
    

    获取更多精彩,请关注「seniusen」!

  • 相关阅读:
    Django 类方式view进行进行用户验证
    Django-发送注册、忘记密码邮件验证-send_mail
    Django-当前菜单激活状态-模版 request | slice
    django url路由参数错误
    video.js不能控制本地视频或者音频播放时长
    Django中url使用命名空间的错误
    python_求相邻数
    scrapy_移除内容中html标签
    scrapy-redis功能简介
    Determining IP information for eth0...failed 错误解决
  • 原文地址:https://www.cnblogs.com/seniusen/p/9865198.html
Copyright © 2020-2023  润新知