1

为什么任何大于列表长度减 1 的切片,如果后面有冒号,则不返回错误?

例子:

IN: a= [1,2,3]
IN: a[999]
OUT: IndexError: list index out of range

IN:a[999:]
OUT: []

谢谢!

4

3 回答 3

3

解释 Python 的切片符号是 SO 答案。引用格雷格的话:

“如果项目比你要求的少,Python 对程序员很友好。例如,如果你要求 a[:-2] 并且 a 只包含一个元素,你会得到一个空列表而不是错误。有时你会更喜欢错误,所以你必须意识到这可能会发生。”

于 2014-01-20T04:35:02.917 回答
1

我的理解是,通过添加冒号,Python 将返回原始列表的浅表副本,而不是访问原始列表中的项目(例如使用 [index] 表示法时)。此副本对于超出范围界限更为宽容,因此当您为其提供无效界限时,您最终会得到副本的原始初始化,这是一个空列表。

Python 参考

除此之外,查看列表切片的实际底层 C 实现可能会让您或其他人更好地了解“幕后”正在发生的事情:

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;
}

如果下边界大于数组的大小,则立即将其设置为数组的大小。此时,无论上限是否更小,相同,更大,它也会被设置为大小。这将有效地生成一个 0 项数组。最终结果显然意味着新创建的副本将有零项,即一个空列表对象。

于 2014-01-20T04:38:20.763 回答
0

这可能是由于数组的初始化。我试过下面的东西

a=[1,2,3,4,5]
OUT:a[900] IndexError: list index out of range this might array could not able fine 900 element. since length is 5
a[:900]
OUT:[1, 2, 3, 4, 5] get printed, it considering the 5 array element other element as zero. 
a[900:]
OUT:[] consider element above 900 is empty so it printing as zero or empty 
于 2014-01-20T05:16:53.570 回答