If you feel negative indices in slicing is confusing, here's a very easy way to think about it: just replace the negative index with len - index. So for example, replace -3 with len(list) - 3.
The best way to illustrate what slicing does internally is just show it in code that implements this operation:
def slice(list, start = None, end = None, step = 1):
# takeTake care of missing start/end parameters
start = 0 if start is None else start
end = len(list) if end is None else end
# takeTake care of negative start/end parameters
start = len(list) + start if start < 0 else start
end = len(list) + end if end < 0 else end
# nowNow just execute a for-loop with start, end and step
return [list[i] for i in range(start, end, step)]