代码之家  ›  专栏  ›  技术社区  ›  Anh Tú Mai

在Python中,为什么列表的大小不等于其元素大小之和?

  •  0
  • Anh Tú Mai  · 技术社区  · 8 年前

    问题 :在Python程序中,以字节为单位的列表大小小于其所有元素的大小。 这是我要测试的代码。我使用 系统。getsizeof() 以字节形式获取变量的大小。

    import sys
    l = range(10)
    for i in range(0,10):
        print(sys.getsizeof(l[i]))
        i = i + 1
    #and it returns 12 bytes for  each element
    print(sys.getsizeof(l))
    #and it returns 76 , not 120
    

    原因是什么?

    1 回复  |  直到 8 年前
        1
  •  1
  •   JohanL    8 年前

    根据 documentation 对于 sys.getsizeof :

    只考虑直接归属于对象的内存消耗,而不考虑它所引用的对象的内存消耗

    这意味着每个元素的存储需求将不属于数据结构字节数的一部分( list )需要。因此,您必须添加列表的大小和各个元素,以获得存储结构所需的总内存。

    但是内存仍然会(通常)随着列表的增加而增加。这是因为 列表 需要内存来保存对元素的引用。但是,由于底层实现的原因,列表可能会请求或保留比保留其引用实际需要的内存更多的内存。这通常在执行 pop 列表上的操作。这通常不会减少 列表 (您的里程数可能会有所不同):

    >>> import sys
    >>> l = [0,1,2]
    >>> sys.getsizeof(l)
    88
    >>> l.pop()
    2
    >>> l
    [0, 1]
    >>> sys.getsizeof(l)
    88
    >>> l.append(2)
    >>> l
    [0, 1, 2]
    >>> sys.getsizeof(l)
    88
    >>> l.append(3)
    >>> l
    [0, 1, 2, 3]
    >>> sys.getsizeof(l)
    120
    >>> l.pop()
    3
    >>> l
    [0, 1, 2]
    >>> sys.getsizeof(l)
    120
    

    因此,通常在添加新元素时 列表 内存占用将增加,但一旦元素弹出,内存占用不会再次减少。但是,一旦元素 是 弹出后,列表中会有一个“备用”位置,可用于一个新元素(引用),该位置允许列表在不增加内存占用的情况下增加其长度。