We make a list and then select a few slices of it:

list.py
my_list = [3, 5, "green", 5.3, "house", 100, 1]

print(my_list[2:4])
print(my_list[3:-2])
print(my_list[-4:-1])
print(my_list[33:37])

The first print selects every element from index-2 up to, but not including, the index-4, i.e. the 2nd and 3rd elements.

The second print starts at index 3 and goe as far as index -2 (which is the same as index 5 in this list).

The next print starts at index -4 (i.e. index 3) and goes until index -1 (i.e. index 6).

Last, print(my_list[33:37]) tries to access elements of a range that do not exist, but the behaviour of Python is different than when accessing a single element as we saw before. In this case, it returns and empty list instead of showing an error message. This wrapping of slicing calls give us some flexibility when accessing a list, but will requiere us to check, in most cases, that the output is not an empty list.

Terminal/Command Prompt
python list.py
['green', 5.3]
[5.3, 'house']
[5.3, 'house', 100]
[]