Python中对切片赋值的原理是什么

Python中对切片赋值的原理是什么?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。

创新互联建站主营渝北网站建设的网络公司,主营网站建设方案,重庆APP开发公司,渝北h5小程序制作搭建,渝北网站营销推广欢迎渝北等地区企业咨询

有这么个问题::

t = [1, 2, 3]
t[1:1] = [7] 
print t  # 输出 [1, 7, 2, 3]

谁会对列表这么进行赋值呢?但是对于这个输出结果的原因确实值得去再了解下,今天看看Python的源码,了解下原理是什么。

注:本地下载的是Python2.7.6的代码,直接看这个。

在Objects/listobject.c中有一个 PyList_SetSlice 函数,是这么写的::

int
PyList_SetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
{
    if (!PyList_Check(a)) {
        PyErr_BadInternalCall();
        return -1;
    }
    return list_ass_slice((PyListObject *)a, ilow, ihigh, v);
}

有用的一句就是 list_ass_slice ,那么再来看看这个函数的代码::

static int
list_ass_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh, PyObject *v)
{
    /* Because [X]DECREF can recursively invoke list operations on
    this list, we must postpone all [X]DECREF activity until
    after the list is back in its canonical shape.  Therefore
    we must allocate an additional array, 'recycle', into which
    we temporarily copy the items that are deleted from the
    list. :-( */
    PyObject *recycle_on_stack[8];
    PyObject **recycle = recycle_on_stack; /* will allocate more if needed */
    PyObject **item;
    PyObject **vitem = NULL;
    PyObject *v_as_SF = NULL; /* PySequence_Fast(v) */
    Py_ssize_t n; /* # of elements in replacement list */
    Py_ssize_t norig; /* # of elements in list getting replaced */
    Py_ssize_t d; /* Change in size */
    Py_ssize_t k;
    size_t s;
    int result = -1;            /* guilty until proved innocent */
#define b ((PyListObject *)v)
    if (v == NULL)
        n = 0;
    else {
        if (a == b) {
            /* Special case "a[i:j] = a" -- copy b first */
            v = list_slice(b, 0, Py_SIZE(b));
            if (v == NULL)
                return result;
            result = list_ass_slice(a, ilow, ihigh, v);
            Py_DECREF(v);
            return result;
        }
        v_as_SF = PySequence_Fast(v, "can only assign an iterable");
        if(v_as_SF == NULL)
            goto Error;
        /*
        要赋值的长度n
        */
        n = PySequence_Fast_GET_SIZE(v_as_SF);
        vitem = PySequence_Fast_ITEMS(v_as_SF);
    }
    if (ilow < 0)
        ilow = 0;
    else if (ilow > Py_SIZE(a))
        ilow = Py_SIZE(a);
    if (ihigh < ilow)
        ihigh = ilow;
    else if (ihigh > Py_SIZE(a))
        ihigh = Py_SIZE(a);
    norig = ihigh - ilow;
    assert(norig >= 0);
    d = n - norig;
    if (Py_SIZE(a) + d == 0) {
        Py_XDECREF(v_as_SF);
        return list_clear(a);
    }
    item = a->ob_item;
    /* recycle the items that we are about to remove */
    s = norig * sizeof(PyObject *);
    if (s > sizeof(recycle_on_stack)) {
        recycle = (PyObject **)PyMem_MALLOC(s);
        if (recycle == NULL) {
            PyErr_NoMemory();
            goto Error;
        }
    }
    memcpy(recycle, &item[ilow], s);
    if (d < 0) { /* Delete -d items */
        memmove(&item[ihigh+d], &item[ihigh],
            (Py_SIZE(a) - ihigh)*sizeof(PyObject *));
        list_resize(a, Py_SIZE(a) + d);
        item = a->ob_item;
    }
    else if (d > 0) { /* Insert d items */
        k = Py_SIZE(a);
        if (list_resize(a, k+d) < 0)
            goto Error;
        item = a->ob_item;
        printf("关键点\n");
        /*
        把list对应切片后一位的值之后的所有内容向后移动所赋值的大小
        按照上面的python代码这里就是
        原理的t:
        |1|2|3|
        后移一位,因为len([7]) = 1
        |1|空|2|3|把后两个移位
        */
        memmove(&item[ihigh+d], &item[ihigh],
            (k - ihigh)*sizeof(PyObject *));
    }
    /*
    赋值操作,即把[7]赋值到t里的对应位置上
    ilow是1, n是1
    */
    for (k = 0; k < n; k++, ilow++) {
        PyObject *w = vitem[k];
        Py_XINCREF(w);
        item[ilow] = w;
    }
    for (k = norig - 1; k >= 0; --k)
        Py_XDECREF(recycle[k]);
    result = 0;
Error:
    if (recycle != recycle_on_stack)
        PyMem_FREE(recycle);
    Py_XDECREF(v_as_SF);
    return result;
#undef b
}

源码内有详细注释,编程问题的研究最好的解释还是源码。

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。


网页题目:Python中对切片赋值的原理是什么
标题URL:http://bzwzjz.com/article/jegphi.html

其他资讯

Copyright © 2007-2020 广东宝晨空调科技有限公司 All Rights Reserved 粤ICP备2022107769号
友情链接: 手机网站建设 成都网站设计 响应式网站建设 响应式网站设计方案 成都网站建设 成都网站设计 成都网站制作 成都网站制作 手机网站建设 成都网站建设 专业网站建设 网站建设费用 成都营销网站制作 教育网站设计方案 网站设计制作报价 成都品牌网站建设 手机网站制作设计 重庆网站建设 成都h5网站建设 企业网站制作 成都定制网站建设 成都网站制作