元组在Python中占用更少的内存空间: a = (1,2,3) a.__sizeof__()48而列表需要更多的内存空间: b = [1,2,3] b.__sizeof__()64Python内存管理内部会发生什么?解决方法:我假设您正在使用CPython和64...

元组在Python中占用更少的内存空间:
>>> a = (1,2,3)
>>> a.__sizeof__()
48
而列表需要更多的内存空间:
>>> b = [1,2,3]
>>> b.__sizeof__()
64
Python内存管理内部会发生什么?
解决方法:
我假设您正在使用CPython和64位(我在CPython 2.7 64位上获得了相同的结果).在其他Python实现中可能存在差异,或者如果您有32位Python.
无论实现如何,列表都是可变大小的,而元组是固定大小的.
因此元组可以直接在结构中存储元素,另一方面,列表需要一个间接层(它存储指向元素的指针).这个间接层是一个指针,在64位系统上是64位,因此是8字节.
但列表还有另一件事:它们过度分配.否则list.append将始终是O(n)操作 – 使其分摊O(1)(快得多!!!)它过度分配.但现在它必须跟踪分配的大小和填充的大小(元组只需要存储一个大小,因为分配和填充的大小总是相同).这意味着每个列表必须存储另一个“大小”,在64位系统上是64位整数,再为8个字节.
因此列表需要比元组多至少16个字节的内存.为什么我说“至少”?因为过度分配.过度分配意味着它分配的空间超出了需要.但是,过度分配的数量取决于您创建列表的“方式”以及追加/删除历史记录:
>>> l = [1,2,3]
>>> l.__sizeof__()
64
>>> l.append(4) # triggers re-allocation (with over-allocation), because the original list is full
>>> l.__sizeof__()
96
>>> l = []
>>> l.__sizeof__()
40
>>> l.append(1) # re-allocation with over-allocation
>>> l.__sizeof__()
72
>>> l.append(2) # no re-alloc
>>> l.append(3) # no re-alloc
>>> l.__sizeof__()
72
>>> l.append(4) # still has room, so no over-allocation needed (yet)
>>> l.__sizeof__()
72
图片
我决定创建一些图像以配合上面的解释.也许这些都很有帮助
这是(示意性地)在您的示例中存储在内存中的方式.我强调了红色(自由手)循环的差异:
这实际上只是一个近似值,因为int对象也是Python对象,CPython甚至可以重用小整数,因此内存中对象的一个??可能更精确的表示(尽管不是可读的)将是:
有用的链接:
> tuple struct in CPython repository for Python 2.7
> list struct in CPython repository for Python 2.7
> int struct in CPython repository for Python 2.7
请注意__sizeof__并没有真正返回“正确”的大小!它只返回存储值的大小.但是,当您使用sys.getsizeof时,结果会有所不同:
>>> import sys
>>> l = [1,2,3]
>>> t = (1, 2, 3)
>>> sys.getsizeof(l)
88
>>> sys.getsizeof(t)
72
有24个“额外”字节.这些是真实的,这是__sizeof__方法中没有考虑的垃圾收集器开销.那是因为你通常不应该直接使用魔术方法 – 使用知道如何处理它们的函数,在这种情况下:sys.getsizeof(实际上是adds the GC overhead到__sizeof__返回的值).
本文标题为:python – 为什么元组在内存中占用的空间少于列表?


基础教程推荐
- Python比较“+”和append()增加列表元素 2023-09-04
- Python运算符之Inplace运算符的使用教程 2022-10-20
- Python WindowsError:[错误3]尝试重命名时系统找不到指定的文件 2023-11-14
- python学习笔记 day37 进程池 2023-09-03
- 如何创建像top unix命令这样的python shell脚本? 2023-11-10
- python类别数据数字化LabelEncoder VS OneHotEncoder区别 2022-10-20
- windows安装python2.7.12和pycharm2018教程 2023-09-03
- python-如何在缺少内存的情况下将缺少记录的大型xyz文件网格化 2023-11-12
- python中playwright结合pytest执行用例的实现 2023-08-04
- Python实现免费音乐下载器 2023-08-04