From the official documentation:
For a negative step, the contents of the range are still determined by the formula r[i] = start + step*i, but the constraints are i >= 0 and r[i] > stop.
r[i] > stop means that
stop will never be part of the sequence. Thus, to end the range at 0, the first index, you have to wrie
range(len(list)-1, -1, -1), where the second argument is one
step further than the last element you want to be included in the range.
range(5, 0, -1) contains
5, 4, 3, 2, 1, since it stops when the next element (0) would have been smaller or equal to the second argument (0).
Why list slicing works the way it does is just because that is how the python interpreter was made to understand it. You can think of negative indexes as normal indexes but backwards (starting at -1, not -0).
[1, 2, 3, 4][-1:0:-1] does not work for reversing the list, since it stops one element before index 0, returning
[1,2,3,4][-1:-1:-1] does not work since the first element is the element to stop at, so the returned list is empty. If you omit
stop, the slice just includes the rest of the list in that direction (
[1,2,3,4][1:] == [2,3,4] and
[1,2,3,4][:3] == [1,2,3]). Thus there is another way to reverse the order of lists in python: