python迭代器面试题_python面试题之“该死的for循环系列”(一)

本文深入探讨了Python中的生成器和迭代器,通过一个具有迷惑性的面试题,解释了生成器的惰性计算特性。在代码分析中,详细阐述了生成器表达式的运行过程,以及如何在不进行迭代的情况下保持生成器的状态。最后,通过实际执行顺序展示了生成器在for循环中的行为,以及如何在最后得到输出结果20,21,22,23。
摘要由CSDN通过智能技术生成

这是一道魔性面试题,难倒了无数英雄好汉……

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 都没有参与运算,

当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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值