def add(n,i): return n+i def test(): for i in range(4): yield i g=test() for n in [1,10]: g=(add(n,i) for i in g) print(n) print(list(g))
10 [20, 21, 22, 23]
第一个函数add就是实现了一个简单的加法运算 第二个函数test是一个生成器函数,若是调用它会返回一个生成器 g=test(),这一行调用了生成器函数,因此此刻g就是一个生成器(它的本质仍是迭代器) 而后执行for循环,这里迷惑人的就是这个for循环,为了减小它的魔性,咱们把for循环拆开来看: 当n = 1时: 执行了:g=(add(n,i) for i in g) 当n = 10时: 执行了:g=(add(n,i) for i in g)
乍一看这两行代码仍是有点迷糊,可是咱们要知道,生成器有个最大的特性就是惰性,当你不进行迭代时它就不进行运算,想要对生成器进行迭代有如下几种方法:
第一种:for循环,for循环的本质就是调用了iter和next方法进行了迭代
第二种:调用next方法
第三种:调用send方法
第四种:数据类型强制转换,好比使用list()强制转换。
只要没有以上四种方法进行迭代,那么生成器就没有进行运算,因此在上面的for循环中不管是n=1时仍是n=10时,生成器 g 都没有参与运算,python
当n = 1时,g=(add(n,i) for i in g),这个表达式的结果g 就是一个表达式,没有进行运算,g的值就是一个表达式(add(n,i) for i in g),括号里面的g其实是test(),因此g = (add(n,i) for i in test()),仅此而已
当n = 10时,g=(add(n,i) for i in g),把n=1时的g的结果带入进去就是g=(add(n,i) for i in (add(n,i) for i in test()))面试
当整段代码执行到print(list(g))语句以前,g的值就是一段代码,或者你能够称之为算法,没有进行任何运算,里面的n就是n,g就是g
不过此时由于代码是按照流程执行的,而且for循环已经执行完毕,因此n的值等于10算法
当执行print(list(g))语句时,生成器才开始输出数据,此时执行最后一个g的赋值语句:
g=(add(n,i) for i in (add(n,i) for i in test()))
这时 n 的值等于10(由于代码是按照流程执行的,for循环已经执行完了,n的最终结果就是10),其中后面的(add(n,i) for i in test())这段代码的结果依然是个生成器,迭代后应为[10,11,12,13],因此最终的结果能够理解成:(add(n,i) for i in [10,11,12,13]),因此最终结果为:20,21,22,23函数