python sys.getsizeof 方法 returns 同种列表的不同大小
python sys.getsizeof method returns different size of same kind of lists
我在 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) returns 96 而 sys.getsizeof(b) returns 120
所以谁能帮我理解为什么会这样?
PS:我只是在尝试 map 函数
由于您的第一个列表 a
是根据文字定义的,因此它的创建大小为 "to fit",而第二个列表 b
在运行时动态增长,实时扩大在 python 知道是否有元素之前容纳更多元素。
这就是为什么您会得到不同尺寸的原因。
列表根据多种因素在内部增长和缩小。它是一个实现细节。例如,在我的 CPython 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
如您所见,列表的大小在增加,但有时我得到相同的字节大小,直到 "grows" 仅在特定点。这是为了节省计算能力增长一次而不是每次增长都增长。
Python 知道列表 a
有多长,所以它正好那么长。
Python 不知道列表 b
到底有多长,因为 map()
是惰性的,所以列表必须随着项目的添加而增长。内存分配相对耗时,因此当它需要更多 space 时,Python 会为比您添加的项目更多的项目添加空间,以避免每次都必须分配内存。这意味着动态生成的列表中经常有空位。
如果这 24 个字节的内存对您来说真的很重要,您可以简单地指示 Python 通过切片来制作 b
的副本:b[:]
。由于 Python 知道 b
有多长,因此副本将恰好具有该数量的插槽并占用尽可能少的内存。
正如 nosklo 所指出的,此行为是一个实现细节。
我在 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) returns 96 而 sys.getsizeof(b) returns 120
所以谁能帮我理解为什么会这样? PS:我只是在尝试 map 函数
由于您的第一个列表 a
是根据文字定义的,因此它的创建大小为 "to fit",而第二个列表 b
在运行时动态增长,实时扩大在 python 知道是否有元素之前容纳更多元素。
这就是为什么您会得到不同尺寸的原因。
列表根据多种因素在内部增长和缩小。它是一个实现细节。例如,在我的 CPython 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
如您所见,列表的大小在增加,但有时我得到相同的字节大小,直到 "grows" 仅在特定点。这是为了节省计算能力增长一次而不是每次增长都增长。
Python 知道列表 a
有多长,所以它正好那么长。
Python 不知道列表 b
到底有多长,因为 map()
是惰性的,所以列表必须随着项目的添加而增长。内存分配相对耗时,因此当它需要更多 space 时,Python 会为比您添加的项目更多的项目添加空间,以避免每次都必须分配内存。这意味着动态生成的列表中经常有空位。
如果这 24 个字节的内存对您来说真的很重要,您可以简单地指示 Python 通过切片来制作 b
的副本:b[:]
。由于 Python 知道 b
有多长,因此副本将恰好具有该数量的插槽并占用尽可能少的内存。
正如 nosklo 所指出的,此行为是一个实现细节。