python sys.getsizeof方法返回相同大小的列表的不同大小

时间:2018-10-08 16:48:45

标签: python python-3.x sys

我在Python 3.7的IDLE中创建了两个列表,名称分别为 a b 它们在初始化方面会有所不同,但内容是相同的(我认为是这样,但也许我错了)


>>>a = [1,2,3,4]
>>>a
[1, 2, 3, 4]
>>>b = list(map(lambda x:x,a))
>>>b
[1, 2, 3, 4]

但是,当我想借助sys.getsizeof方法了解其大小时 sys.getsizeof(a)返回96,而 sys.getsizeof(b)返回120


所以有人可以帮助我了解为什么会这样吗? PS:我只是尝试使用 map 函数

2 个答案:

答案 0 :(得分:4)

由于您的第一个列表a是根据文字定义的,因此创建时的大小为“适合”,而第二个列表b在运行时会动态增长,并实时进行扩展以适合python知道是否存在元素之前的所有元素。

这就是为什么您得到不同的尺寸。

列表会根据多种因素在内部增长和收缩。这是一个实现细节。例如,在我的CPyhton 3实现中:

import sys

l = []
for x in range(10):
    print(x, sys.getsizeof(l))
    l.append(x)

结果:

0 64
1 96
2 96
3 96
4 96
5 128
6 128
7 128
8 128
9 192

您可以看到列表的大小在增长,但是有时我得到的字节数相同,直到它仅在特定点“增长”为止。这是为了节省计算能力一次增长,而不是每次增长都增长。

答案 1 :(得分:0)

Python知道列表a将有多长,因此它恰好那么长。

Python不知道列表b到底有多长,因为map()是惰性的,因此列表必须随着项目的添加而增长。内存分配是相对耗时的,因此当需要更多空间时,Python会为您增加更多的空间,以免每次都分配内存。这意味着动态生成的列表中通常会有空的插槽。

如果这24个字节的内存对您确实很重要,则可以通过切片b来简单地指示Python复制b[:]。由于Python知道b的长度,因此副本将完全具有该数量的插槽,并占用最少的内存。

正如nosklo所指出的,此行为是实现细节。