美文网首页
Python 推导式+lambda

Python 推导式+lambda

作者: 青铜搬砖工 | 来源:发表于2018-04-07 17:14 被阅读0次

    今天在网上看到一个面试题:

    def multipliers():
        return [lambda x,y=i: y * x for i in range(4)]
    print [m(2) for m in multipliers()]
    

    本来以为结果会是[0,2,4,6]
    输出结果居然为:[6,6,6,6],也真是666.
    感觉很神奇百度了一下,大部分都是从闭包角度讲,感觉云里雾里,例如:
    https://blog.csdn.net/xie_0723/article/details/53925076这一篇讲的就比较详细。
    但是我还是像我这种python新手还是有点难理解。于是我就想从python推导式与lambda方面分析一下。
    下面这个例子与上面的面试题例子运行结果一样:

    temp =[lambda  x :i* x for i in range(4)]
    print [m(2) for m in temp]
    

    首先temp=[]说明返回的是一个列表,for i in range(4)说明这是一个推导式(推导式的作用就是由一个旧的列表生成一个满足条件的新列表,推导式讲解见本人python推导式),产生的新列表是四个元素都是(lambda x : i*x)的列表。
    temp =[lambda x :i* x for i in range(4)]只是声明了这四个匿名函数。
    这个新列表目前是:
    [(lambda x : i*x),(lambda x : i*x),(lambda x : i*x),(lambda x : i*x)],
    只有函数名后面加上()函数才会执行例如上例中的m(2),
    这时候新列表就变成了:
    [(lambda 2 : i*2),(lambda 2 : i*2),(lambda 2: i*2),(lambda 2 : i*2)],
    程序要运行就还要知道i的值,这时候就去找i的值,发现这时候i已经在for循环中变成了3,所以最后输出的结果就是[6,6,6,6]了
    那如何让结果变为[0,2,4,6]呢,上面的博客里也给了例子:

    def multipliers():
        return [lambda x,i=i: i * x for i in range(4)]
    print [m(2) for m in multipliers()]
    

    这样输出的结果就为[0,2,4,6]了
    现在来分析一下这个例子:
    同样我们还是先来转换一下;

    temp =[lambda  x ,i=i:i* x for i in range(4)]
    print [m(2) for m in temp]
    

    这样其实还是不好理解,再来转换一下:

    temp =[lambda  x ,y=i:y* x for i in range(4)]
    print [m(2) for m in temp]
    

    单单看这个匿名函数:lambda x ,y=i:y* x,是不是就是一个求两数之积的匿名函数,并且第二个参数是一个缺省参数,缺省的值为i,同样我们知道参数的缺省值在函数定义的时候就要被指定下来。
    那么这就好理解了,在使用推导式声明四个匿名函数的时候,每一个匿名函数要知道自己的缺省值是什么啊,不然到时候怎么去计算,所以for i in range(4)每一个i值都被y保存下来。
    temp =[lambda x ,y=i:y* x for i in range(4)]生成的四个匿名函数为:
    [(lambda x,y=0 : y*x),(lambda x,y=1 : y*x),(lambda x,y=2 : y*x),(lambda x,y=3 : y*x)]
    那结果就顺利成章了 就是[0,2,4,6]。

    相关文章

      网友评论

          本文标题:Python 推导式+lambda

          本文链接:https://www.haomeiwen.com/subject/nzpyhftx.html