Skip to main content
The 2026 Annual Developer Survey is live— take the Survey today!
Explicitly highlight languages, mostly so the C gets the right syntax applied.
Source Link
Michael come lately

In short, the colons (:) in subscript notation (subscriptable[subscriptarg]) make slice notation -, which has the optional arguments, start, stop, and step:

sliceable[start:stop:step]
sliceable[start:stop:step]

startstart: the beginning index of the slice, it will include the element at this index unless it is the same as stop, defaults to 0, i.e. the first index. If it's negative, it means to start n items from the end.

stopstop: the ending index of the slice, it does not include the element at this index, defaults to length of the sequence being sliced, that is, up to and including the end.

stepstep: the amount by which the index increases, defaults to 1. If it's negative, you're slicing over the iterable in reverse.

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
   0   1   2   3   4   5 
  -6  -5  -4  -3  -2  -1
 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
   0   1   2   3   4   5 
  -6  -5  -4  -3  -2  -1
sequence[start:stop:step]
sequence[start:stop:step]
my_list[-9:]
my_list[-9:]
my_list[-9:None:None]
my_list[-9:None:None]
my_list[-9:len(my_list):1]
my_list[-9:len(my_list):1]
list_copy = sequence[:]
list_copy = sequence[:]
del my_list[:]
del my_list[:]

But you can pass in a negative integer, and the list (or most other standard slicablessliceables) will be sliced from the end to the beginning.

 step_is_negative = step_sign < 0;
step_is_negative = step_sign < 0;
if (step_is_negative) {
    lower = PyLong_FromLong(-1L);
    if (lower == NULL)
        goto error;

    upper = PyNumber_Add(length, lower);
    if (upper == NULL)
        goto error;
}
if (step_is_negative) {
    lower = PyLong_FromLong(-1L);
    if (lower == NULL)
        goto error;

    upper = PyNumber_Add(length, lower);
    if (upper == NULL)
        goto error;
}
else {
    lower = _PyLong_Zero;
    Py_INCREF(lower);
    upper = length;
    Py_INCREF(upper);
}
else {
    lower = _PyLong_Zero;
    Py_INCREF(lower);
    upper = length;
    Py_INCREF(upper);
}

Then, we may need to apply the defaults for start and stop - the—the default then for start is calculated as the upper bound when step is negative:

if (self->start == Py_None) {
    start = step_is_negative ? upper : lower;
    Py_INCREF(start);
}
if (self->start == Py_None) {
    start = step_is_negative ? upper : lower;
    Py_INCREF(start);
}
if (self->stop == Py_None) {
    stop = step_is_negative ? lower : upper;
    Py_INCREF(stop);
}
if (self->stop == Py_None) {
    stop = step_is_negative ? lower : upper;
    Py_INCREF(stop);
}
last_nine_slice = slice(-9, None)
last_nine_slice = slice(-9, None)
>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]
>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]
>>> range(100)[last_nine_slice]
range(91, 100)
>>> range(100)[last_nine_slice]
range(91, 100)
length = 100
last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1)
list_last_nine = list(last_nine_iter)
length = 100
last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1)
list_last_nine = list(last_nine_iter)
>>> list_last_nine
[91, 92, 93, 94, 95, 96, 97, 98, 99]
>>> list_last_nine
[91, 92, 93, 94, 95, 96, 97, 98, 99]

In short, the colons (:) in subscript notation (subscriptable[subscriptarg]) make slice notation - which has the optional arguments, start, stop, step:

sliceable[start:stop:step]

start: the beginning index of the slice, it will include the element at this index unless it is the same as stop, defaults to 0, i.e. the first index. If it's negative, it means to start n items from the end.

stop: the ending index of the slice, it does not include the element at this index, defaults to length of the sequence being sliced, that is, up to and including the end.

step: the amount by which the index increases, defaults to 1. If it's negative, you're slicing over the iterable in reverse.

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
   0   1   2   3   4   5 
  -6  -5  -4  -3  -2  -1
sequence[start:stop:step]
my_list[-9:]
my_list[-9:None:None]
my_list[-9:len(my_list):1]
list_copy = sequence[:]
del my_list[:]

But you can pass in a negative integer, and the list (or most other standard slicables) will be sliced from the end to the beginning.

 step_is_negative = step_sign < 0;
if (step_is_negative) {
    lower = PyLong_FromLong(-1L);
    if (lower == NULL)
        goto error;

    upper = PyNumber_Add(length, lower);
    if (upper == NULL)
        goto error;
}
else {
    lower = _PyLong_Zero;
    Py_INCREF(lower);
    upper = length;
    Py_INCREF(upper);
}

Then, we may need to apply the defaults for start and stop - the default then for start is calculated as the upper bound when step is negative:

if (self->start == Py_None) {
    start = step_is_negative ? upper : lower;
    Py_INCREF(start);
}
if (self->stop == Py_None) {
    stop = step_is_negative ? lower : upper;
    Py_INCREF(stop);
}
last_nine_slice = slice(-9, None)
>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]
>>> range(100)[last_nine_slice]
range(91, 100)
length = 100
last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1)
list_last_nine = list(last_nine_iter)
>>> list_last_nine
[91, 92, 93, 94, 95, 96, 97, 98, 99]

In short, the colons (:) in subscript notation (subscriptable[subscriptarg]) make slice notation, which has the optional arguments start, stop, and step:

sliceable[start:stop:step]

start: the beginning index of the slice, it will include the element at this index unless it is the same as stop, defaults to 0, i.e. the first index. If it's negative, it means to start n items from the end.

stop: the ending index of the slice, it does not include the element at this index, defaults to length of the sequence being sliced, that is, up to and including the end.

step: the amount by which the index increases, defaults to 1. If it's negative, you're slicing over the iterable in reverse.

 +---+---+---+---+---+---+
 | P | y | t | h | o | n |
 +---+---+---+---+---+---+
   0   1   2   3   4   5 
  -6  -5  -4  -3  -2  -1
sequence[start:stop:step]
my_list[-9:]
my_list[-9:None:None]
my_list[-9:len(my_list):1]
list_copy = sequence[:]
del my_list[:]

But you can pass in a negative integer, and the list (or most other standard sliceables) will be sliced from the end to the beginning.

step_is_negative = step_sign < 0;
if (step_is_negative) {
    lower = PyLong_FromLong(-1L);
    if (lower == NULL)
        goto error;

    upper = PyNumber_Add(length, lower);
    if (upper == NULL)
        goto error;
}
else {
    lower = _PyLong_Zero;
    Py_INCREF(lower);
    upper = length;
    Py_INCREF(upper);
}

Then, we may need to apply the defaults for start and stop—the default then for start is calculated as the upper bound when step is negative:

if (self->start == Py_None) {
    start = step_is_negative ? upper : lower;
    Py_INCREF(start);
}
if (self->stop == Py_None) {
    stop = step_is_negative ? lower : upper;
    Py_INCREF(stop);
}
last_nine_slice = slice(-9, None)
>>> list(range(100))[last_nine_slice]
[91, 92, 93, 94, 95, 96, 97, 98, 99]
>>> range(100)[last_nine_slice]
range(91, 100)
length = 100
last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1)
list_last_nine = list(last_nine_iter)
>>> list_last_nine
[91, 92, 93, 94, 95, 96, 97, 98, 99]
Commonmark migration
Source Link
Community Bot

start: the beginning index of the slice, it will include the element at this index unless it is the same as stop, defaults to 0, i.e. the first index. If it's negative, it means to start n items from the end.

 

stop: the ending index of the slice, it does not include the element at this index, defaults to length of the sequence being sliced, that is, up to and including the end.

 

step: the amount by which the index increases, defaults to 1. If it's negative, you're slicing over the iterable in reverse.

start: the beginning index of the slice, it will include the element at this index unless it is the same as stop, defaults to 0, i.e. the first index. If it's negative, it means to start n items from the end.

 

stop: the ending index of the slice, it does not include the element at this index, defaults to length of the sequence being sliced, that is, up to and including the end.

 

step: the amount by which the index increases, defaults to 1. If it's negative, you're slicing over the iterable in reverse.

start: the beginning index of the slice, it will include the element at this index unless it is the same as stop, defaults to 0, i.e. the first index. If it's negative, it means to start n items from the end.

stop: the ending index of the slice, it does not include the element at this index, defaults to length of the sequence being sliced, that is, up to and including the end.

step: the amount by which the index increases, defaults to 1. If it's negative, you're slicing over the iterable in reverse.

added 118 characters in body
Source Link
Aaron Hall

It's interesting that ranges also take slices:

>>> range(100)[last_nine_slice]
range(91, 100)
>>> length = 100
>>> last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1)
>>> list_last_nine = list(last_ninelast_nine_iter)

and now:

>>> list_last_nine
[91, 92, 93, 94, 95, 96, 97, 98, 99]
>>> length = 100
>>> last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1)
>>> list_last_nine = list(last_nine)
>>> list_last_nine
[91, 92, 93, 94, 95, 96, 97, 98, 99]

It's interesting that ranges also take slices:

>>> range(100)[last_nine_slice]
range(91, 100)
length = 100
last_nine_iter = itertools.islice(list(range(length)), length-9, None, 1)
list_last_nine = list(last_nine_iter)

and now:

>>> list_last_nine
[91, 92, 93, 94, 95, 96, 97, 98, 99]
Show the source.
Source Link
Aaron Hall
Loading
deleted 1 character in body
Source Link
Aaron Hall
Loading
Remove extraneous "of"
Source Link
ShadowRanger
Loading
fix some nonsense...
Source Link
Aaron Hall
Loading
added 197 characters in body
Source Link
Aaron Hall
Loading
deleted 22 characters in body
Source Link
Aaron Hall
Loading
added 224 characters in body
Source Link
Aaron Hall
Loading
added 206 characters in body
Source Link
Aaron Hall
Loading
added 272 characters in body
Source Link
Aaron Hall
Loading
added 653 characters in body
Source Link
Aaron Hall
Loading
Source Link
Aaron Hall
Loading
lang-py