python - 为什么两个相同的列表有不同的内存占用?

我创建了两个列表l1l2,但是每个列表都有不同的创建方法:

import sys

l1 = [None] * 10
l2 = [None for _ in range(10)]

print('Size of l1 =', sys.getsizeof(l1))
print('Size of l2 =', sys.getsizeof(l2))

但输出让我感到惊讶:

Size of l1 = 144
Size of l2 = 192

使用列表推导式创建的列表在内存中的大小更大,但是这两个列表在 Python 中是相同的。

这是为什么呢?这是 CPython 内部的东西,还是其他解释?

最佳答案

当您编写 [None] * 10 时,Python 知道它需要一个正好包含 10 个对象的列表,因此它会准确分配它。

当您使用列表推导式时,Python 不知道它需要多少。因此,随着元素的添加,它会逐渐增加列表。对于每次重新分配,它分配的空间比立即需要的空间多,因此它不必为每个元素重新分配。结果列表可能比需要的要大。

在比较大小相似的列表时,您会看到这种行为:

>>> sys.getsizeof([None]*15)
184
>>> sys.getsizeof([None]*16)
192
>>> sys.getsizeof([None for _ in range(15)])
192
>>> sys.getsizeof([None for _ in range(16)])
192
>>> sys.getsizeof([None for _ in range(17)])
264

您可以看到第一种方法只分配所需的内容,而第二种方法会定期增长。在这个例子中,它为 16 个元素分配了足够的空间,并且在到达第 17 个元素时必须重新分配。

https://stackoverflow.com/questions/51526242/

相关文章:

linux - 如何在不保留目录结构的情况下 tar 目录?

python - 资源,客户端和 session 之间的boto3差异?

python - 规范化数据框的列

python - 在 Linux 上通过 Python 脚本截取屏幕截图

python - UnicodeEncodeError : 'charmap' codec can'

linux - 使用 Bash 按列拆分命令输出?

linux - 将 cron 选项卡设置为工作日的特定时间

python - 什么时候应该使用 Flask.g?

linux - 提取并删除目录中的所有.gz - Linux

python - 如何从 Python 中的 URL 读取图像数据?