zoukankan      html  css  js  c++  java
  • 一道好题

    一道好题

    题目如下:

    def f():
        l = []
        for i in range(4):
            def a(x):
                return x * i
    
            l.append(a)
        return l
    
    
    print([e(2) for e in f()]) # [6, 6, 6, 6]
    

    代码可以翻译成这样:

    def f():
        l = []
        for i in range(4):
            def a(x):
                return x * i
    
            l.append(a)
        return l
    
    
    l_curr = []
    for e in f():
        l_curr.append(e(2))
    print(l_curr)
    

    代码的执行过程如下:

    • 代码从上到下执行,进入函数f()

    • 初始化空列表l

    • 进入for循环

    • i=0,执行l.append(a)

      python调用函数时加括号表示调用函数的最终执行结果,不加括号表示调用函数对象,所以这里列表追加的时函数对象。此时l=[<function f.<locals>.a at 内存地址1>]

    • i=1,执行l.append(a)

      此时l=[<function f.<locals>.a at 内存地址1>,<function f.<locals>.a at 内存地址2>]

    • i=2,执行l.append(a)

      此时l=[<function f.<locals>.a at 内存地址1>,<function f.<locals>.a at 内存地址2>],<function f.<locals>.a at 内存地址3>

    • i=3,执行l.append(a)

      此时l=[<function f.<locals>.a at 内存地址1>,<function f.<locals>.a at 内存地址2>],<function f.<locals>.a at 内存地址3>,<function f.<locals>.a at 内存地址4>

    • 函数f()执行完毕,return l

      此时l=[<function f.<locals>.a at 内存地址1>,<function f.<locals>.a at 内存地址2>],<function f.<locals>.a at 内存地址3>,<function f.<locals>.a at 内存地址4>

    • 初始化空列表l_curr

    • 进入for循环,开始遍历f()

      此时的f()是带括号的,所以引用的是最终返回的列表

    • 遍历第一个元素<function f.<locals>.a at 内存地址1>,执行2 * 3 = 6,这个函数存储的ii的引用,此时的i=3

    • 遍历第二个元素<function f.<locals>.a at 内存地址2>,执行2 * 3 = 6,这个函数存储的ii的引用,此时的i=3

    • 遍历第三个元素<function f.<locals>.a at 内存地址3>,执行2 * 3 = 6,这个函数存储的ii的引用,此时的i=3

    • 遍历第四个元素<function f.<locals>.a at 内存地址4>,执行2 * 3 = 6,这个函数存储的ii的引用,此时的i=3

    • 遍历完毕,返回列表l_curr=[6, 6, 6, 6]

    类比

    def f():
        l = []
        for i in range(4):
            def a(x, i=i):
                return x * i
    
            l.append(a)
        return l
    
    
    l_curr = []
    for e in f():
        l_curr.append(e(2))
    print(l_curr)
    

    区别是:def a(x, i=i)

    在这个程序中,函数f()中的列表l每次追加的函数a中存储的i当前的i值,而不是引用。所以四次的i值分别为0, 1, 2, 3

    所以最终的结果为l_curr=[0, 2, 4, 6]

  • 相关阅读:
    51-maven私有库神坑之:“Downloading: http://repo.maven.apache.org/maven2/”
    50-maven 仓库配置
    49-2017年第八届蓝桥杯国赛试题及详解(Java本科B组)
    21-matlab 迷宫题
    20-matlab全排列-函数调用
    52-python 画图二维
    51-python3 pandas读写excel
    48-设置tomcat虚拟路径的两种方法(Eclipse、tomcat、IDEA)
    19-matlab知识点复习二
    【剑指offer】二叉搜索树的后序遍历序列
  • 原文地址:https://www.cnblogs.com/junsircoding/p/15664894.html
Copyright © 2011-2022 走看看