为何遍历返回列表的生成器需两层循环?能否用单层循环实现?
问题分析与解决方案
你的问题核心在于**test_generator是生成器函数,但它每次yield的是完整列表,而非单个元素**,所以第一层循环拿到的是整个列表对象,自然需要第二层循环才能取出里面的值。
为什么会出现两层循环的需求?
看你test_generator的实现逻辑:
def test_generator(self): record = [] c = 0 self.counter = self.counter + 1 if (self.counter <= 50): while c < 5: record.append(self.counter + 1) c = c + 1 yield record # 这里一次性产出了整个列表
你先把5个元素塞进record列表,再把整个列表作为生成器的单次产出值。所以生成器每次迭代返回的是列表,而非单个元素,这就是必须两层循环的原因。
如何只用一层循环获取元素?
有两种实用的解决思路:
方法1:修改生成器,逐个产出元素
直接放弃先攒列表的逻辑,每次yield单个元素:
class test: def __init__(self): self.counter = 0 def test_generator(self): self.counter = self.counter + 1 if self.counter <= 50: c = 0 while c < 5: yield self.counter + 1 # 逐个产出单个数值 c = c + 1
这时遍历生成器时,item直接就是单个值,一层循环足够:
t = test() while True: for item in t.test_generator(): # 注意规范写法:用实例调用方法,而非类调用 print(item) # 加终止条件避免无限空转 if t.counter >= 50: break
方法2:不修改生成器,直接展开嵌套列表
如果不想改动生成器函数,可以用“打平”嵌套结构的方式,让代码看起来是一层循环:
import itertools t = test() while True: # 用itertools.chain把生成器返回的列表逐个展开 for i in itertools.chain.from_iterable(t.test_generator()): print(i) if t.counter >= 50: break
这种方法底层还是做了两层循环,但代码层面只需要写一层。
另外提个小细节:你的代码里test.test_generator(t)是用类调用实例方法(手动传实例参数),虽然Python允许,但更规范的写法是用实例直接调用:t.test_generator()。
内容的提问来源于stack exchange,提问作者pikk
相关产品推荐
相关产品推荐

