Python中generator及map对象的数据存储位置相关疑问
核心原因:
del仅删除变量引用,map对象仍持有原始tuple的强引用 Python 中的变量本质是指向内存对象的标签,你执行del t1仅删除了当前命名空间下t1这个标签,不会直接删除它指向的tuple对象:只要还有其他对象持有该tuple的强引用,GC 就不会清理这块内存。
map 对象在初始化时会自动将传入的可迭代对象(也就是你创建的t1、t2)保存为内部属性,持有它的强引用。你用getsizeof拿到的48字节仅为map对象本身的结构体大小,不统计它引用的其他对象的内存占用,所以看不到它持有的tuple的内存开销很正常。
为什么删除
t1后仍能调用next(m1)取值 map对象的迭代逻辑非常简单:每次调用__next__方法时,先从内部持有的原始可迭代对象中取下一个元素,再传入你指定的映射函数执行,返回最终结果。
因为m1始终持有原t1对应tuple的强引用,tuple本身没有被GC回收,自然可以正常从中读取后续元素。
你可以用以下代码验证该逻辑:
import gc t = tuple(range(10)) m = map(lambda x: x, t) del t gc.collect() # 依然可以完整迭代出所有元素 print(list(m))
关于生成器存储逻辑的认知补充
你之前对生成器的认知基本正确:迭代器/生成器本身不会存储所有迭代值,但它们会持有原始可迭代对象的引用:
- 如果原始可迭代对象是已经预生成的容器(tuple、list等),那么值本身就存储在容器的内存空间中,迭代器只是按需读取
- 如果原始可迭代对象本身是惰性生成的(比如直接传
range(1000)而非转成tuple),那么才会每次迭代时临时计算生成值,没有额外的预存储开销
内容的提问来源于stack exchange,提问作者EBDS
相关产品推荐
相关产品推荐

