嵌套for循环中生成器提前抛出StopIterator问题排查
问题原因与解决办法
你遇到的问题核心是**reversed()返回的是一次性迭代器,而非可重复遍历的序列**。
当你在生成器开头定义lower_index = reversed(upper_index)时,这个变量是一个迭代器对象。第一次执行最内层for up, down in zip(upper_index, lower_index)循环时,会把lower_index里的所有元素(共8个)全部取完,迭代器直接耗尽。后续的外层循环再进入内层时,lower_index已经没有剩余元素了,zip()函数只要其中一个迭代器耗尽就会停止,所以不会再产生任何新的(up, down, counter)元组,生成器自然提前结束,导致你只拿到8个结果就抛出StopIterator。
方案1:将迭代器转为可重复遍历的列表
把lower_index转换成列表,这样每次循环都是遍历完整的列表元素,不会出现迭代器耗尽的问题:
def generator(): counter = 0 upper_index = [0, 1, 2, 3, 7, 6, 5 , 4] lower_index = list(reversed(upper_index)) # 转为列表,支持重复遍历 for i in range(4): for _ in range(2): for up, down in zip(upper_index , lower_index): yield (up, down, counter) counter += 1
方案2:每次内层循环前重新创建迭代器
如果不想额外占用内存存储列表,可以把reversed()的调用放到最内层循环之前,每次进入内层循环都生成新的迭代器:
def generator(): counter = 0 upper_index = [0, 1, 2, 3, 7, 6, 5 , 4] for i in range(4): for _ in range(2): lower_index = reversed(upper_index) # 每次循环重新生成迭代器 for up, down in zip(upper_index , lower_index): yield (up, down, counter) counter += 1
内容的提问来源于stack exchange,提问作者Olumide
相关产品推荐
相关产品推荐

