python-3.x 为什么两个创建方式不同但大小相同的列表的sys.getsizeof会有差异?

gorkyyrv  于 2023-01-14  发布在  Python
关注(0)|答案(1)|浏览(91)

我定义了如下两个列表:

import sys
lst = list(range(1, 10, 1))
llst = ([1, 2, 3, 4, 5, 6, 7, 8, 9])
print(sys.getsizeof(llst), sys.getsizeof(lst))

这是我看到的输出:
152 128
为什么这两个列表的大小不同,而它们似乎具有相同数量的元素?
我在Windows 11上使用Python 3.10.5。

2izufjch

2izufjch1#

差异来自“超额分配”,来自源代码:

/* This over-allocates proportional to the list size, making room
     * for additional growth.  The over-allocation is mild, but is
     * enough to give linear-time amortized behavior over a long
     * sequence of appends() in the presence of a poorly-performing
     * system realloc().
     * Add padding to make the allocated size multiple of 4.
     * The growth pattern is:  0, 4, 8, 16, 24, 32, 40, 52, 64, 76, ...
     * Note: new_allocated won't overflow because the largest possible value
     *       is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t.

但确切的行为是实现细节!
在Python 3.10中:

import sys

lst1 = list(range(1, 10))
lst2 = [item for item in range(1, 10)]
lst3 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
lst4 = []
for i in range(1, 10):
    lst4.append(i)

print(sys.getsizeof(lst1)) # 136
print(sys.getsizeof(lst2)) # 184
print(sys.getsizeof(lst3)) # 136
print(sys.getsizeof(lst4)) # 184

在Python 3.5.1中:

import sys

lst1 = list(range(1, 10))
lst2 = [item for item in range(1, 10)]
lst3 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
lst4 = []
for i in range(1, 10):
    lst4.append(i)

print(sys.getsizeof(lst1)) # 192
print(sys.getsizeof(lst2)) # 192
print(sys.getsizeof(lst3)) # 136
print(sys.getsizeof(lst4)) # 192

我很确定当.append()被调用时会发生这种情况(列表理解也是如此),这就是为什么在两个版本中,lst2lst4都有最大的大小。
看起来像是在Python 3.10中,对于lst1,解释器从range对象说OK,我知道(__len__ and __length_hint__)它需要10个元素,所以我构建了一个10个元素的列表,不需要过度分配。

相关问题