Python同地址整数独立存储与存入列表时大小差异疑问
解答
你的猜测是对的,差值完全来自列表存储元素引用的指针空间,根本不存在“同一个整数在不同位置存储长度不同”的情况,核心是两个认知偏差导致的误判:
1. sys.getsizeof() 不会递归统计引用对象的内存
这个函数的返回值只包含传入对象自身的内存占用,不会算它指向的其他对象的大小:
- 调用
sys.getsizeof(i)拿到的28字节,就是整数5这个对象本身的全部内存:24字节是Python所有对象都有的固定头信息(包含类型指针、引用计数等),剩下4字节是存储整数数值的空间,和你测算的32位存储结论一致。 - 调用
sys.getsizeof(ls)拿到的数值,从头到尾都和列表里存的整数本身大小没关系,只算列表这个结构体自己的开销。
2. CPython列表存的是指针,不是元素本身
CPython的列表是典型的动态数组结构,它的内存分为两部分:
- 固定开销部分:就是你测到的空列表56字节,包含列表的引用计数、类型指针、当前元素长度、预分配容量、指向底层存储数组的指针这些元信息,和存多少元素无关。
- 动态数组部分:数组里每个位置存的不是元素的实际内容,而是指向对应元素对象的内存地址(即指针)。你用的是64位Ubuntu系统,单个指针的固定长度就是8字节。
当列表里只有1个元素时,底层数组刚好分配了存1个指针的空间,总大小就是56+8=64字节,和你的测试结果完全匹配。你之前错误地把这8字节指针空间算成了整数本身的存储位,才会得出“列表里的整数是64位”的错误结论。
3. 为什么ls[0]和i的内存地址完全一致?
Python默认对[-5, 256]区间的小整数做全局驻留,这个区间内的整数在解释器启动时只会创建一次全局唯一实例。不管你把5赋值给独立变量i,还是放到列表ls里,本质都是存了一个指向这个唯一整数实例的指针:
- 变量
i本身是个指针,存的值是0x955ea0(整数5的地址) - 列表底层数组的第一个位置,存的也是
0x955ea0这个地址值
从头到尾内存里只有一份5的整数对象,始终占28字节,从来没有生成过64位版本的拷贝。你调用sys.getsizeof(ls[0])拿到28字节的结果,就是最直接的证据。
快速验证方法
你可以往列表里依次加2个、3个元素,会发现每加一个元素,sys.getsizeof(ls)的增量固定是8字节,不管你存的是小整数、大整数、字符串还是自定义对象,这个增量都不变——这8字节就是指针的固定长度,和存储的元素本身大小没有任何关系。
内容的提问来源于stack exchange,提问作者nova24
相关产品推荐
相关产品推荐

