Discuss / Python / 求高手给个栈进出分析

求高手给个栈进出分析

Topic source

水滴竹沙

#1 Created at ... [Delete] [Delete and Lock User]

def count(): fs = [] for i in range(1, 4): def f(): return i*i fs.append(f) return fs

f1, f2, f3 = count()

与 def count(): def f(j): def g(): return j*j return g fs = [] for i in range(1, 4): fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f() return fs

ilovehusky

#2 Created at ... [Delete] [Delete and Lock User]

第一段代码:

def count():
    fs = []
    for i in range(1, 4):
        def f():
             return i*i
        fs.append(f)
    return fs

f1, f2, f3 = count()

在for循环里定义了函数f的行为,每次for循环的时候,执行了fs.append(f),在fs里插入了i×i,第一次fs里插入的是1×1;第二次for循环,fs的下一个位置插入了i×i,但这次i是2,实际上是2×2,那么fs保存的第一个i×i实际上也是2×2。后面同理。 第二段代码:

def count():
    def f(j):
        def g():
            return j*j
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i))
    return fs

这段代码的2、3、4、5、6行都是定义了函数行为,还没有调用呢,在for循环里调用了fs.append(f(i)),在这个调用里,i变量的值为上面定义的f(j)函数里那个j变量赋值了,j成了i的一个拷贝;第一次执行for,fs里插入的是函数g,g里面的内容是j×j,实际上是1×1;第二次执行for,fs里插入的是函数g,g里的内容是j×j,实际上是2×2, 请再注意一点,当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数: f1 = lazy_sum(1, 3, 5, 7, 9) f2 = lazy_sum(1, 3, 5, 7, 9) f1==f2 False f1()和f2()的调用结果互不影响。注意原文,现在fs里保存了两个函数g,他们是不同的,不影响,也就是,第一个g里面是1×1,第二个g是2×2。最后的返回fs,里面有3个g函数,各不同,分别赋值给f1、f2、f3后,就是1,4,9了,怎么样,够明白不

水滴竹沙

#3 Created at ... [Delete] [Delete and Lock User]

最后一句是正解,谢谢!

感谢2楼的分析,懂了

机修贾森

#5 Created at ... [Delete] [Delete and Lock User]

2楼精辟!

Mr羊习

#6 Created at ... [Delete] [Delete and Lock User]

第一个函数返回的list里面存放的三个函数里面的i 其实都指向的是同一个栈区地址 第二个里面返回的list是预先分配好不同的i的栈区地址然后才押进去

第一段代码里面:fs.append(f)运行时,仅仅是在list fs中添加了f函数,而这个函数并没有运行,所以一开始里面并没有具体的值。直到后来运行时,i已经是3时,才计算。所以结果都是9。小白不知道理解的对不对。

仧者

#8 Created at ... [Delete] [Delete and Lock User]

【每次for循环的时候,执行了fs.append(f),在fs里插入了i×i,第一次fs里插入的是1×1;第二次for循环,fs的下一个位置插入了i×i,但这次i是2,实际上是2×2,那么fs保存的第一个i×i实际上也是2×2。后面同理】

意思是第一次插入的是1x1, 第二次for循环在fs的下一个位置插入2x2, 第三次在fs的下一个位置插入3x3,如果这样的话,fs不就是[1,4,9] 了么,为什么最后保存的数变成9了呢,1和4哪里去了?求解

即为什么到最后函数返回时,i就变成3了????

感谢@ilovehusky 的分析。

谢谢分享,一目了然


  • 1
  • 2

Reply