Python Slicing is a flexible tool to build new lists out of an existing list. Python supports slice notation for any sequential data types like lists, tuples, strings, bytes, bytearrays, and ranges. Also, any new data structure can also be added to its support as well. This is greatly used in Pandas and NumPy libraries, which are so popular in Machine Learning and Data Science. This is a very good example of “learn once, use everywhere”.
There is also a step value, which can be used in any of the above notations:
The best way to remember this is that the :stop value represents the first value that is not in the selected slice. So, the difference between stop and start will be the number of elements selected (if step is 1, the default).
The ASCII art diagram is helpful too for remembering how slices work:
Another way to remember how slice notation works is to think of the indices as pointing between characters, with the left edge of the first character numbered as 0. Then the right edge of the last character of a string of n characters has index n.
Let's take an example to understand slice assignment:
The other feature in slice notation is that start or stop may be a negative number too, which means it counts from the end of the array instead of the beginning. So:
Similarly, step may be a negative number too:
Python is also very kind to the programmer if there are fewer items than you ask for. For example, if you ask for a[:-2] from list a and a only contains one element, you get an empty list instead of an error. But Sometimes you would prefer the error, so you have to be aware that this may happen too.
The slicing operator  is really being used in the above code with a slice() object using the : notation (which is only valid within ), i.e.:
is equivalent to:
Slice objects also behave slightly different depending on the number of arguments it has, similarly to range(), i.e. both slice(stop) and slice(start, stop[, step]) are supported. To skip specifying a given argument, a programmer might use None, so that e.g. a[start:] is equivalent to a[slice(start, None)] or a[::-1] is equivalent to a[slice(None, None, -1)].
While the :-based notation is very helpful for simple slicing operations, the explicit use of slice() objects simplifies the programmatic generation of slicing.