• 关于Python 中切片的问题


    偶然发现一个有趣的问题:

    list = ['a','b','c','d','e']
    print(list[10:])                                                                                                              ·      

    大家猜猜这个打印结果是什么,事实上打印的是[] 空列表,并不会出现IndexError的问题,那么如果是 print(list[10])呢,这时就会出现index error的问题,这是为什么呢?

    笔者查看了下Python的源码,切片调用的是PyList_GetSlice方法,获取元素调用的是 PyList_GetItem 方法,源码如下:

    PyObject *
    PyList_GetItem(PyObject *op, Py_ssize_t i)
    {
        if (!PyList_Check(op)) {
            PyErr_BadInternalCall();
            return NULL;
        }
      //超出索引范围会报错
    if (i < 0 || i >= Py_SIZE(op)) { if (indexerr == NULL) { indexerr = PyUnicode_FromString( "list index out of range"); if (indexerr == NULL) return NULL; } PyErr_SetObject(PyExc_IndexError, indexerr); return NULL; } return ((PyListObject *)op) -> ob_item[i]; }

    可以得知当索引为10时,超出了list size 故而引发index 异常,然而切片代码如下:

    static PyObject *
    list_slice(PyListObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
    {
        PyListObject *np;
        PyObject **src, **dest;
        Py_ssize_t i, len;
        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);
        len = ihigh - ilow;
        np = (PyListObject *) PyList_New(len);
        if (np == NULL)
            return NULL;
    
        src = a->ob_item + ilow;
        dest = np->ob_item;
        for (i = 0; i < len; i++) {
            PyObject *v = src[i];
            Py_INCREF(v);
            dest[i] = v;
        }
        return (PyObject *)np;
    }
    
    PyObject *
    PyList_GetSlice(PyObject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
    {
        if (!PyList_Check(a)) {
            PyErr_BadInternalCall();
            return NULL;
        }
        return list_slice((PyListObject *)a, ilow, ihigh);
    }

    可以看出即使切片的两个值大于元素个数也不会引发异常。

  • 相关阅读:
    NHibernate之旅(14):探索NHibernate中使用视图
    NHibernate之旅(18):初探代码生成工具使用
    NHibernate之旅(15):探索NHibernate中使用存储过程(上)
    接下来5年中有用的10项开发技能
    NHibernate之旅(22):探索NHibernate一级缓存
    NHibernate之旅(24):探索NHibernate二级缓存(下)
    NHibernate之旅(17):探索NHibernate中使用存储过程(下)
    NHibernate之旅(11):探索多对多关系及其关联查询
    Python入门示例系列18 条件控制
    .NET计划之配置ASP.NET运行环境
  • 原文地址:https://www.cnblogs.com/mlmy/p/13266902.html
Copyright © 2020-2023  润新知