Python生成器表达式输出结果存疑,请求代码逻辑解释
为什么这段Python代码的输出和预期不符?
先看你写的代码:
x= (i for i in range(3)) print(x) for j in x: print(j) for i in x: print(i)
你预期输出是0 1 2 0 1 2,但实际运行后输出是0 1 2,问题出在生成器的一次性迭代特性上。
核心原因:生成器是“一次性”的
你用(i for i in range(3))创建的是一个生成器对象,它和列表有本质区别:
- 列表会把所有元素提前存在内存里,每次迭代都能从头遍历;
- 生成器不会预存元素,只会在迭代时逐个生成元素,一旦迭代到末尾,就彻底耗尽了,再也不会产生新元素。
代码执行的详细流程
- 第一行创建生成器
x,此时它还没生成任何元素,print(x)会输出类似<generator object <genexpr> at 0x...>的生成器标识。 - 进入外层
for j in x循环,开始迭代生成器:- 第一次迭代,生成器产出第一个元素
0,赋值给j,执行print(j)输出0。 - 接着进入内层
for i in x循环,继续迭代同一个生成器:- 生成器从上次暂停的位置继续,产出
1,输出1; - 再产出
2,输出2; - 此时生成器已经走到末尾,没有更多元素了,内层循环结束。
- 生成器从上次暂停的位置继续,产出
- 外层循环尝试继续迭代
x,但生成器已经耗尽,没有新元素可以产出,外层循环直接终止。
- 第一次迭代,生成器产出第一个元素
所以最终只会输出0 1 2,而不是你预期的重复两次。
怎么改成预期的效果?
把生成器改成列表即可,用方括号代替圆括号:
x= [i for i in range(3)] # 列表推导式,不是生成器 print(x) for j in x: print(j) for i in x: print(i)
列表可以被多次迭代,外层循环每次取j时,内层循环都能从头遍历整个列表,就能得到你想要的0 1 2 0 1 2输出。
内容的提问来源于stack exchange,提问作者Yogesh Patel
相关产品推荐
相关产品推荐

