Python - 嵌套空列表的内存大小

Python - In-memory size of nested empty lists

一个对象在内存中的大小可以通过sys.getsizeof获得。

不出所料,[] 的大小小于 [[]] 的大小。在我的机器上,我得到以下尺寸:

>>> sys.getsizeof([])
36
>>> sys.getsizeof([[]])
40

现在,无论我有多少嵌套空列表,我总是得到相同的大小:

>>> sys.getsizeof([[[]]])
40
>>> sys.getsizeof([[[[]]]])
40

嵌套空列表的大小似乎有上限是什么原因?

阅读 the documentation 会告诉我在调用 getsizeof

Only the memory consumption directly attributed to the object is accounted for, not the memory consumption of objects it refers to.

因为 [] 是一个容器,根据 getsizeof,它的大小是它自己的大小加上它包含的引用的大小,而不是引用对象的大小。

因此,如果[]的大小为36,而引用的大小为4,则[[]]的大小为36+4 ], 因此 40.

现在,[[[]]] 只不过是 [x],其中 x 是对 [[]] 的引用。因此,[[[]]] 的大小是 [] 的大小加上引用的大小,因此 40 也是。

大小只指最外层的对象,不包括嵌套的对象。从 getsizeof 的角度来看,对象大小只是对象的大小加上对象中包含的指针的大小,而不是被指向的对象。从以下可以看出:

>>> import sys
>>> sys.getsizeof([])
64
>>> sys.getsizeof([[]])
72
>>> sys.getsizeof([[[]]])
72
>>> sys.getsizeof([[],[]])
80
>>> sys.getsizeof([[[]],[[]]])
80

如果您想获得总内存占用量,您将需要递归查找对象的大小或使用其他一些内存分析。

此外,如果您正在编写自己的对象并希望 getsizeof 正确 return 大小,您可以实现自己的 __sizeof__ 方法。例如:

import sys
class mylist:
    def __init__(self, iterable):
        self.data = list(iterable)

    def __sizeof__(self):
        return object.__sizeof__(self) + \
            sum(sys.getsizeof(v) for v in self.__dict__.values()) + \
            sum(sys.getsizeof(item) for item in self.data)

original_data = [[1,2,3], [1,2,3]]
print(sys.getsizeof(original_data))
foo = mylist(original_data)
print(sys.getsizeof(foo))

结果:

~/code_snippets$ python3 sizeof_list.py 
80
336