>>> import sys
>>> sys.getsizeof([])
32
>>> sys.getsizeof([1])
36
>>> sys.getsizeof('')
25
>>> sys.getsizeof('a')
26
>>> sys.getsizeof('cam')
28
我对参考和紧凑阵列有一个模糊的概念。
在Python中,列表是参照数组,因此它们使用更多内存来存储引用元素的内存位置。
我只能从上面的例子中推断出列表中的一个整数占用了额外的4个字节(32 + 4)。 字符串是字符数组。一个unicode字符应该占用2位。
为什么空字符串占用25个字节?
为什么空列表占用32个字节?
答案 0 :(得分:3)
答案 1 :(得分:3)
我只能从上面的例子中推断出列表中的一个整数占用了额外的4个字节(32 + 4)。
不,你在考虑这个错误。
getsizeof
不是递归的。特别是,列表的大小只是列表“header”的大小加上其成员的引用数组。 (在通常的CPython实现中,这些引用是PyObject *
指针)列表中的对象类型没有区别,只有多少对象。
(另外,请记住,列表通常在结尾处有松弛。因此,3个元素的列表实际上可能包含4个引用的数组,最后一个是空指针。)
同时,数字1
本身可能不会占用任何存储空间。大多数Python实现实习生小整数,因此有一个1
对象内置于Python中,无论你为数字1
创建了多少个引用,它们都只是对同一个对象的引用;你永远不会创建另外4个字节。
为什么空字符串占用25个字节?
字符串与列表类似,字符串“header”,加上一个数组 - 只是一个字符数组,而不是对象的引用。因为它们是不可变的,所以不需要松弛,这使得更容易预测尺寸。如果系统上的空字符串为25个字节,则表示字符串标头为25个字节,因此'abc'
将为28个字节,'abcde'
为30个字节,依此类推。 (我在这里假设Python 2.x或Python 3.3+;如果你在3.0-3.2,每个字符实际上是2或4个字节。虽然Python 3.3+中的字符串实际上有点复杂;阅读如果你真的想知道,那就是来源。)
为什么空列表占用32个字节?
因为这是列表标题的大小。
如果您想查看这些标题中的实际内容,您需要查看实现的来源。假设你正在使用CPython,你可以找到它here。 (这指向最新的主干版本,此时为3.5alpha;您可以使用default
或2.7
或您关注的任何版本替换网址中的3.3
。)
例如,列表在C API中的类型为PyListObject
。您可以搜索源代码,也可以猜测listobject.h
可能是定义PyUnicodeObject
的文件。而there,您将看到定义类型的C结构。总结成员,有一个通用标题包含所有类型所需的信息(如refcount),指向实际数组的指针和分配的计数。
答案 2 :(得分:2)
unicode字符应占用2位。为什么是一个空字符串 占据25位?
因为Python字符串(字节或unicode)是一个对象,而不是一个unicode字符。
>>> s = "a"
>>> type(s)
<type 'str'>
>>> dir(s)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
>>>