为什么两个相同的列表有不同的内存占用? [英] Why do two identical lists have a different memory footprint?

查看:48
本文介绍了为什么两个相同的列表有不同的内存占用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

导入系统l1 = [无] * 10l2 = [范围内的_无(10)]print('l1 的大小 =', sys.getsizeof(l1))print('l2 的大小 =', sys.getsizeof(l2))

但是输出让我很惊讶:

l1 的大小 = 144l2 的大小 = 192

使用列表推导式创建的列表在内存中更大,但在 Python 中这两个列表在其他方面是相同的.

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

解决方案

当你写 [None] * 10 时,Python 知道它需要一个正好包含 10 个对象的列表,所以它准确地分配

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

比较以相似大小创建的列表时,您可以看到此行为:

<预><代码>>>>sys.getsizeof([无]*15)184>>>sys.getsizeof([无]*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 个时不得不重新分配.

I created two lists l1 and l2, but each one with a different creation method:

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))

But the output surprised me:

Size of l1 = 144
Size of l2 = 192

The list created with a list comprehension is a bigger size in memory, but the two lists are identical in Python otherwise.

Why is that? Is this some CPython internal thing, or some other explanation?

解决方案

When you write [None] * 10, Python knows that it will need a list of exactly 10 objects, so it allocates exactly that.

When you use a list comprehension, Python doesn't know how much it will need. So it gradually grows the list as elements are added. For each reallocation it allocates more room than is immediately needed, so that it doesn't have to reallocate for each element. The resulting list is likely to be somewhat bigger than needed.

You can see this behavior when comparing lists created with similar sizes:

>>> 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

You can see that the first method allocates just what is needed, while the second one grows periodically. In this example, it allocates enough for 16 elements, and had to reallocate when reaching the 17th.

这篇关于为什么两个相同的列表有不同的内存占用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆