python定义空列表 长度_Python: 浅析列表的变长变短

前言

Python 的列表(list)是一个非常灵活的数组,可以随意调整长度。正是因为这种便利,使得我们会情不自禁地去修改数组以满足我们的需求,其中相比于insert, pop 等等而言, append 用法更常见。

有像这样使用:

>>> test = []

>>> test.append(1)

>>> test.append({2})

>>> test.append([3])

>>> print test

# 输出

[1, set([2]), [3]]

也有像这样使用的:

test = []

for i in range(4):

test.append(i)

print test

# 输出

[0, 1, 2, 3]

这样用很开心,也很满足。

但其实只要遇到能够动态修改数据长度场景,我们都应该马上反应过来一点,那就是内存管理的问题。

如果运行效率和便捷性同时满足的话,那简直就是大大的福音呀。

然而,上帝为你开启一扇窗的同时肯定也已经关上了一扇门了!

吝啬的初始化

深受预分配知识的熏陶,我们也是觉得 list 在初始化是有分配一定的长度的,要不然每次都申请内存那得多 ”low“ 啊。

然后实际上 list 真的就是这么 ”low“:

import sys

test = []

test_1 = [1]

print sys.getsizeof(test)

print sys.getsizeof(test_1) - sys.getsizeof(test)

# 输出

72 # 空列表内存大小,也是 list 对象的总大小

8 # 代表增加一个成员,list 增加的大小 ( 此大小为对象指针的长度 )

我们的猜测是,list 在定义之后,会预先分配好一个一定大小的池用来塞数据,以避免动不动就申请内存。

但是在上面的实验看出,一个成员的列表,比一个空列表,长度仅仅只是大了 8 字节(对象指针的大小),如果真的存在这样一个预分配的池,那么在预分配个数之内添加成员,两者的内存大小应该是保持不变才对。

所以可以猜测这块 list 应该是没有这样的一个预分配内存池。这里需要来个实锤

PyObject *

PyList_New(Py_ssize_t size)

{

PyListObject *op;

size_t nbytes;

if (size < 0) {

PyErr_BadInternalCall();

return NULL;

}

/* Check for overflow without an actual overflow,

* which can cause compiler to optimise out */

if ((size_t)size > PY_SIZE_MAX / sizeof(PyObject *))

return PyErr_NoMemory();

// list对象指针的缓存

if (numfree) {

numfree--;

op =

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值