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]

  • 相关阅读:
    软件工程第一次作业
    Python正则表达式学习摘要
    个人作业——软件工程实践总结作业
    个人作业——软件评测
    软件工程实践2019第五次作业--结对编程的实现
    软件工程实践2019第四次作业
    软件工程实践2019第三次作业
    软件工程实践2019第二次作业
    软件工程实践2019第一次作业
    个人作业——软件工程实践总结&个人技术博客
  • 原文地址:https://www.cnblogs.com/junsircoding/p/15664894.html
Copyright © 2011-2022 走看看