zoukankan      html  css  js  c++  java
  • 对 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」!

  • 相关阅读:
    Python 通过最低位判断数字是偶数还是奇数
    C语言 windows下Ansi和UTF-8编码格式的转换
    C语言 Ubuntu系统 UTF-8 文字处理
    C语言 使用char字符实现汉字处理
    C# GUI应用 实现 2048游戏
    Docker部署Minio
    Ubuntu18.04开启root
    Ubuntu18.04安装Docker
    docker安装mysql
    idea启动项目端口被占用
  • 原文地址:https://www.cnblogs.com/seniusen/p/9865198.html
Copyright © 2011-2022 走看看