我已经读过python列表应该占用64个字节,并且列表中的每个条目都应该“花费”另外8个字节。我决定测试一下。但是,在测试时,我发现这取决于您将项目添加到列表的方式。为什么sys.getsizeof
和ob1
的{{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,但我认为他们的答案与另一个似乎与熊猫有关的答案不同。
答案 0 :(得分:0)
开销是由于Python在list
中分配了一些额外的“槽”,以便您能够例如append
到列表,而无需分配新的内存并在其中复制旧列表。
您可以通过在列表中添加一些值来查看:
>>> obj1.append('!')
>>> print(sys.getsizeof(obj1))
264
>>> obj2.append('!')
>>> print(sys.getsizeof(obj2))
272
如您所见,可以添加到obj1
而不会增长,而obj2
需要分配一个新的“块”。
这是一个实现细节,但是当您动态增加列表的大小时,此行为通常很好,因为这会减少程序的内存碎片(并提高速度)。