列表和sys.getsizeof不一致

时间:2019-04-22 21:09:13

标签: python list memory python-3.7

我已经读过python列表应该占用64个字节,并且列表中的每个条目都应该“花费”另外8个字节。我决定测试一下。但是,在测试时,我发现这取决于您将项目添加到列表的方式。为什么sys.getsizeofob1的{​​{1}}在下面的代码中不一致?

obj2

import sys test1 = 'This is a string.' obj1 = [] obj2 = ['T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 's', 't', 'r', 'i', 'n', 'g', '.'] obj3 = list(test1) for i in range(len(test1)): obj1.append(test1[i]) print(sys.getsizeof(obj1)) print(obj1) print(sys.getsizeof(obj2)) print(obj2) print(sys.getsizeof(obj3)) print(obj3) >>>264 >>>['T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 's', 't', 'r', 'i', 'n', 'g', '.'] >>>200 >>>['T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 's', 't', 'r', 'i', 'n', 'g', '.'] >>>264 >>>['T', 'h', 'i', 's', ' ', 'i', 's', ' ', 'a', ' ', 's', 't', 'r', 'i', 'n', 'g', '.'] 报告我期望的大小(64 + 8 * 17 = 200)。使用obj2函数后的开销是多少?构造列表后可以以某种方式消除开销吗?

我已经阅读了相关主题here,但我认为他们的答案与另一个似乎与熊猫有关的答案不同。

1 个答案:

答案 0 :(得分:0)

开销是由于Python在list中分配了一些额外的“槽”,以便您能够例如append到列表,而无需分配新的内存并在其中复制旧列表。

您可以通过在列表中添加一些值来查看:

>>> obj1.append('!')
>>> print(sys.getsizeof(obj1))
264

>>> obj2.append('!')
>>> print(sys.getsizeof(obj2))
272

如您所见,可以添加到obj1而不会增长,而obj2需要分配一个新的“块”。

这是一个实现细节,但是当您动态增加列表的大小时,此行为通常很好,因为这会减少程序的内存碎片(并提高速度)。