如何理解Python中列表结构的内存占用?

3

我想了解Python的内存占用情况。

以下是代码:

import sys
list1 = [1]
list2 = [1,2]
list3 = [1,2,3]
list4 = [1,2,3,4]
list5 = [1,2,3,4,5]
list6 = ['1',2,3,4,5,6]
list7 = [1,2,'3','4',5,6,7]
list8 = [1,2,3,'sdsd',5,6,7,8]
list9 = [1,2,3,4,5,6,7,8,9]

print('list1 size is :', sys.getsizeof(list1))
print('list2 size is :', sys.getsizeof(list2))
print('list3 size is :', sys.getsizeof(list3))
print('list4 size is :', sys.getsizeof(list4))
print('list5 size is :', sys.getsizeof(list5))
print('list6 size is :', sys.getsizeof(list6))
print('list7 size is :', sys.getsizeof(list7))
print('list8 size is :', sys.getsizeof(list8))
print('list9 size is :', sys.getsizeof(list9))

这是结果:

list1 size is : 64
list2 size is : 72
list3 size is : 120
list4 size is : 120
list5 size is : 120
list6 size is : 152
list7 size is : 120
list8 size is : 120
list9 size is : 152

我的困惑问题是:

  • 为什么list6list7大,且等于list9

  • 为什么list3-list5等于list7-list8`?

感谢大家。


当我运行这段代码时,我得到了list6 size is : 104的输出,并且它们都像预期的那样单调递增。 - alex
1
请查看 https://dev59.com/Sbzpa4cB1Zd3GeqPMYJG,这个链接回答了大部分的问题。为什么6突然变得更大与预先分配列表的一些内部启发式有关。详细讨论这个问题有点无关紧要,因为它甚至可能在Python版本和架构之间不同。如果您真的感兴趣,请参考源代码进行查询。 - deceze
1个回答

2

首先,getsizeof 返回的是以字节为单位的大小。

因此,让我们将其分解成更小的步骤。

整数、字符串和空列表的代码示例:

import sys

list1 = [1]
list2 = ['a']
list3 = []

print('list 1:', sys.getsizeof(list1))
print('list 2:', sys.getsizeof(list2))
print('list 3:', sys.getsizeof(list3))

响应

list 1: 64
list 2: 64
list 3: 56

您可以看到,一个空列表使用了56个字节,而一个包含字符串或整数的列表使用相同数量的64个字节。

每个列表区域(步骤)将保留8个字节的最小数量以包含数据,看下面的示例。

import sys

list1 = [1]
list2 = [1,2]
list3 = [1,2,3]
list4 = [1134,2234,3334]
list5 = ['ab','t',3334]

print('list 1:', sys.getsizeof(list1))
print('list 2:', sys.getsizeof(list2))
print('list 3:', sys.getsizeof(list3))
print('list 4:', sys.getsizeof(list4))
print('list 5:', sys.getsizeof(list5))

列表3-5使用相同的空间,唯一相等的是列表项的数量。

list 1: 64
list 2: 72
list 3: 80
list 4: 80
list 5: 80

所以为什么你看到的字节数相等,我认为你应该在Python的工作方式中找到答案,这是它的基本工作方式。

我无法解释更多关于它的逻辑或者不是,因为这可以始终讨论。

就像你在计算机上保存文本文档一样,它会为文件保留一些空间,而文件的实际字节大小通常不同,我认为Python做了类似的事情。


要了解Python如何重新定位列表,您可以查看list_resize()的实现。 重定位之前的注释之一是:“增长模式为:0、4、8、16、24、32、40、52、64、76……”。 - Olvin Roght

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接