You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中Tuple、List与Array的内存占用对比疑问

列表/元组与array.array存储float的内存差异及sys.getsizeof的疑问

核心结论

  • 列表和元组确实存储指向PyFloatObject的指针,而array.array直接存储C语言原始的float/double值,不存在指向Python对象的指针。
  • 测试结果与预期的差异,核心原因是sys.getsizeof()的特性:它仅返回当前对象自身占用的内存,不会递归计算其引用的其他对象的内存。

详细解释

先回顾《流畅的Python》中的描述:

这就是float数组比float元组紧凑得多的原因:数组是存储float原始值的单个对象,而元组由多个对象组成——元组本身以及其中每个float对象。

这句话的核心是总内存占用,而非sys.getsizeof()直接返回的单个对象内存:

  1. 元组/列表的内存构成:
    • 元组/列表本身是一个Python对象,底层C结构包含指向PyObject的指针数组,每个指针指向独立的PyFloatObject实例(即Python中使用的float对象)。
    • sys.getsizeof(tuple)返回的是元组结构体+指针数组的内存大小,但每个PyFloatObject自身还要占用额外内存(Python 3.11 64位环境下,一个float对象约占48字节)。要计算元组的总内存,需将元组本身的大小加上所有元素float对象的内存总和。
  2. array.array的内存构成:
    • array.array('d')(存储双精度float)的底层是一块连续内存缓冲区,直接存储C语言的double值(每个占8字节),无额外Python对象开销。
    • sys.getsizeof(array)返回的是数组结构体加上所有原始float值的内存总和,无需额外计算其他对象的内存。

测试结果差异的原因

如果仅对比sys.getsizeof()返回的元组和数组大小,可能会觉得元组的大小没大多少(比如包含10个float的元组,sys.getsizeof返回40 + 108 = 120字节;而array.array('d')返回数组结构体(约96字节) + 108 = 176字节),这看似和“数组更紧凑”的结论矛盾,但这是因为你只计算了元组本身的内存,没算每个float对象的内存。

若计算总内存:

  • 元组总内存:120 + 10*48 = 600字节
  • 数组总内存:176字节

此时就能体现出数组的紧凑性,与书中描述一致。

底层结构确认

你提到的结论是正确的:Python列表和元组的底层C结构确实是存储指向PyObject的指针数组,每个float元素都是独立的PyFloatObject实例;而array.array直接存储原始数值,没有中间的Python对象层。

内容的提问来源于stack exchange,提问作者Andrey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 19:35:23