当前位置: 首页 > 面试题库 >

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

仉俊能
2023-03-14
问题内容

我创建了两个列表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个元素时不得不重新分配。



 类似资料:
  • 问题内容: 我有两个表,它们的列数是可变的。(我不知道有多少列或名称会是什么),例如表A和表B。 表A: 表B 询问: 当TableA和TableB都具有相同名称的列时,我无法区分两个不同的列。例如,两个表都有“名称”列,此查询将导致: 我正在寻找一种区分两个表的方法。最好使用预定义的列名称,例如。 我知道“ AS”关键字,但是问题是我不知道这些列名称将是什么。(我不知道TableA或TableB

  • 我还将列表一中的和成员的每个哈希代码与列表二中成员的哈希代码进行了比较。而且没有区别。但是如果我比较完整列表的hashcode,就有区别了。我不知道为什么。我很无助。 也许有人能帮我。请提前向我致以最诚挚的问候和感谢。

  • 问题内容: 考虑以下两种情况: (转到Playground链接) 第二个打印9.120000000000001,实际上很好 但是,为什么第一行打印9.12,但末尾没有…01?Go是否会将两个未类型化的常数相乘,并在编译时将它们简单地替换为9.12文字? 问题答案: 根据规格: 常量表达式总是精确地求值;中间值和常量本身可能需要比该语言中任何预声明类型支持的精度大得多的精度。 以来 是一个常数表达式

  • 问题内容: 拥有Java代码 该字符串将分配在相同的内存位置(或多倍): 是否多次启动同一程序(并行)执行? 可能的答案: 我目前是C#开发人员(尽管在上个千年中使用Java编程)。 我之所以问这个问题,是因为我相信.NET CLR和Java(JVM)之间是相同的,我希望得到.NET应用程序的答案(但由于经常遇到的“应用程序”池术语而引起疑问)。 答案是 字符串 实习生池由同一JVM或.NET C

  • 我正在运行以下JOOQ查询: table和joinTable都有id作为主键名称,但最终获取实体类包含joinTable的id和table的其余列。如果我重新排序表,结果相似,我有表的ID和joinTable的其余列。

  • 为什么它不打印“processTextPosition:ContainsKey”?