生成器转列表时机不同为何导致计算结果存在差异?
生成器遍历耗尽导致的结果差异问题解析
兄弟,我一眼就看出你踩了Python生成器的经典坑!咱们来一步步拆解问题根源:
核心问题:生成器的「一次性遍历」特性
zip()函数返回的是一个生成器对象,这种对象的本质是「惰性迭代器」——它只会在遍历的时候逐个生成元素,而且只能被完整遍历一次,遍历结束后就会被彻底耗尽,再去遍历就拿不到任何元素了。
第一段代码的执行逻辑
咱们看这段代码:
alphas = np.arange(5) args = zip(np.arange(5), np.arange(5)) # args是生成器 output = [np.mean([ a+b for a, b in args]) for _ in alphas]
当列表推导式第一次循环时:
[a+b for a,b in args]会把生成器args的所有元素((0,0)、(1,1)...(4,4))全部遍历完,生成列表[0,2,4,6,8],np.mean计算后得到4.0。- 但这时候生成器
args已经被彻底榨干了!后面四次循环再去遍历args时,[a+b for a,b in args]会得到一个空列表,而np.mean([])的结果就是nan,所以你看到后面四个结果都是nan。
第二段代码的修复原理
第二段代码里你加了关键的一行:
args = list(args) # 将生成器转为列表
列表是可重复遍历的容器,它会一次性把生成器的所有元素存储起来,后续每次循环去遍历它时,都能拿到完整的元素集合,所以五次循环每次都能计算出相同的均值4.0,结果自然全是4.0。
小总结
- 生成器(比如
zip()、(x for x in ...)创建的生成器)是「一次性」的,遍历完就空了 - 如果需要多次遍历迭代器的内容,记得把它转换成列表、元组这类可重复访问的容器
内容的提问来源于stack exchange,提问作者Ghazi Felhi
相关产品推荐
相关产品推荐

