python--yield

在网上看到一道题目,要求推导出结果,尝试了一会儿,还是搞不明白具体的推导过程

def add(n, i):
 return n+i

def test():
    for i in range(4):
        yield i

g = test()

for n in [1, 10, 5]:
    g = (add(n, i) for i in g)

print(list(g)) # 结果是 [15, 16, 17, 18] 

生成器不进行迭代就不会运算, 可以理解为仅仅是个表达式
g = (add(n, i) for i in g)
for 循环三次g并没有进行计算,循环三次后n等于5
这时候

n = 5
g = (add(n, i) for i in (add(n, i) for i in (add(n, i) for i in test())))
print(list(g)) # 结果是 [15, 16, 17, 18] 

使用yield的生成器函数必须使用next()来调用才会被执行,list数据类型强转也可以读取生成器的值。

上面是定义了一个生成器test
g = test() 是创建一个生成器对象,此时并没有执行。

三次循环分别为:
n=1时 g = (add(n, i) for i in g) 这里如果取值:list(g) 为 [1,2,3,4]
n=10时 g = (add(n, i) for i in (add(n, i) for i in g)) 这里如果取值,list(g) 为 [20,21,22,23]
n=5时 g=(add(n, i) for i in (add(n, i) for i in (add(n, i) for i in g))) 这时如果取值为[15, 16, 17, 18]

谢谢老师,我去把yield再看下,这个Debug看不出来执行过程,有什么方法可以看出来它的执行过程吗?

g = (add(n, i) for i in g) 也是生成器对象
test函数不用yield也是一样的结果

def test():
    return list(range(4))

可以打断点调试看看
改成g = [add(n, i) for i in g] 的运行结果会不同