08月13, 2020

16. 向 List 插入元素

List 最常用的几种操作有:

  • 插入元素,比如 insert、append、extend;
  • 弹出元素,比如 pop、delete;
  • 切片 slice;

今天主要看一下 List 如何增加元素。最简单的增加 1 个元素,代码如下:

// Objects/listobject.c:285
static int
ins1(PyListObject *self, Py_ssize_t where, PyObject *v)
{
    Py_ssize_t i, n = Py_SIZE(self);
    PyObject **items;

    // 省略一些无关的错误处理代码

    // 调整 List 大小
    if (list_resize(self, n+1) < 0)
        return -1;

   // 计算负数位置
    if (where < 0) {
        where += n;
        if (where < 0)
            where = 0;
    }
    if (where > n)
        where = n;

    // 插入位置之后的元素后移
    items = self->ob_item;
    for (i = n; --i >= where; )
        items[i+1] = items[i];

    // 增加 v 的索引,并将 v 设置到插入位置。
    Py_INCREF(v);
    items[where] = v;
    return 0;
}

省略一些无关代码,插入一个元素的过程比较简单:

  • 调整 List 大小到 n + 1;
  • 将插入位置之后的元素后移 1 个单元,腾出插入数据的空间;
  • 在 where 处插入数据;

需要注意的是 list_resize 并一定会真的发生 realloc 操作,实际上它只在预分配空间不足,或者预分配空间太多时才发生内存操作,其他时候只是调整 ob_size 的数值。插入 1 个元素的过程看起来这样:

img

本文链接:http://www.thinkinpython.com/post/deep_python_vm_16.html

-- EOF --