1

Why does any slice higher than the length of a list minus 1, not return an error if there is a colon after it?

Example:

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

IN:a[999:]
OUT: []

Thanks!

Tim
  • 11,710
  • 4
  • 42
  • 43
KGS
  • 277
  • 2
  • 4
  • 11

3 Answers3

3

Explain Python's slice notation is the SO answer. To quote Greg:

"Python is kind to the programmer if there are fewer items than you ask for. For example, if you ask for a[:-2] and a only contains one element, you get an empty list instead of an error. Sometimes you would prefer the error, so you have to be aware that this may happen."

Community
  • 1
  • 1
Tyler Jones
  • 424
  • 2
  • 10
  • 24
1

My understanding is that by adding the colon, Python is returning a shallow copy of the original list, rather than accessing items from the original list (such as when using a[index] notation). This copy is more forgiving about being out of range bounds, so when you feed it invalid bounds, you end up with the original initalization of the copy, which is an empty list.

Python Reference

Along with this, looking at the actual underlying C implementation for list slicing might allow you or others to better understand what's happening "under the hood":

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

If the low boundary is larger than the size of the array, immediately it is set to the size of the array. At this point, regardless of whether the high bound is smaller, the same, larger, it will be set to the size also. This will effectively make for a 0-item array. The end result obviously means that the newly created copy will have zero items i.e. an empty list object.

omgitsfletch
  • 469
  • 1
  • 4
  • 15
0

This might due intialize of array. I tried below thing

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