They're defined by a starting point, and ending point, and an increment with the following syntax:
Python will then return a new list containing myList[start], myList[start+increment], myList[start+2*increment],... up to but not including myList[end]. This is very important, and bears repeating: myList[end] will not be included in the slice.
Each parameter is optional. If not provided start defaults to 0, end defaults to the length of the list, and increment defaults to 1. The first colon is always necessary (to indicate Python should make a slice rather than access a single element), but if the increment isn't specified the second colon can be omitted.
Hence, by way of example, if exampleList = [0,1,2,3,4,5,6,7,8,9,10] , Python will do the following:
exampleList[3:6] will evaluate to [3,4,5] (6 is not included!) exampleList[2:8:2] will evaluate to [2,4,6] exampleList[5:5] will evaluate to  (endpoints still aren't included!) exampleList[:4] will evaluate to [0,1,2,3] (the first 4 elements of the list) exampleList[-2:] will evaluate to [9,10] (the last two elements, remember that negative indices wrap around) exampleList[:] will evaluate to [0,1,2,3,4,5,6,7,8,9,10] (an exact copy of myList) exampleList[::3] will evaluate to [0,3,6,9] (every third element)
Slices can also be assigned to. For example, using the same exampleList as above, typing
exampleList[3:5] = [0,0,0]
will replace the [3,4] slice in exampleList with [0,0,0], so the updated exampleList will be [1,2,0,0,0,5,6,7,8,9,10].