Taking a portion of elements from a list or tuple is a very common operation. For example, consider the following list:
>>> L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
How do you get the first 3 elements?
A naive approach:
>>> [L[0], L[1], L[2]]
['Michael', 'Sarah', 'Tracy']
This is considered naive because if you want to extend it to get the first N elements, this method becomes impractical.
To get the first N elements (i.e., elements with indices from 0 to N-1), you can use a loop:
>>> r = []
>>> n = 3
>>> for i in range(n):
... r.append(L[i])
...
>>> r
['Michael', 'Sarah', 'Tracy']
For operations that frequently involve taking elements within a specified index range, using a loop is quite cumbersome. Therefore, Python provides the slice operator to greatly simplify such operations.
For the problem above, to get the first 3 elements, you can use slicing in just one line of code:
>>> L[0:3]
['Michael', 'Sarah', 'Tracy']
L[0:3] means starting from index 0 and taking elements up to (but not including) index 3. That is, indices 0, 1, and 2, which are exactly 3 elements.
If the first index is 0, it can be omitted:
>>> L[:3]
['Michael', 'Sarah', 'Tracy']
You can also start from index 1 and take 2 elements:
>>> L[1:3]
['Sarah', 'Tracy']
Similarly, since Python supports L[-1] to get the last element, it also supports negative slicing. Try this:
>>> L[-2:]
['Bob', 'Jack']
>>> L[-2:-1]
['Bob']
Remember that the index of the last element is -1.
Slicing operations are very useful. Let’s first create a sequence from 0 to 99:
>>> L = list(range(100))
>>> L
[0, 1, 2, 3, ..., 99]
You can easily extract a segment of this sequence using slicing. For example, the first 10 numbers:
>>> L[:10]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
The last 10 numbers:
>>> L[-10:]
[90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
Numbers from index 10 to 19 (11th to 20th elements):
>>> L[10:20]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
The first 10 numbers, taking one out of every two:
>>> L[:10:2]
[0, 2, 4, 6, 8]
All numbers, taking one out of every five:
>>> L[::5]
[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
You can even make a copy of the entire list by just writing [:]:
>>> L[:]
[0, 1, 2, 3, ..., 99]
A tuple is also a kind of sequence, the only difference being that a tuple is immutable. Therefore, you can also perform slicing operations on a tuple, and the result will still be a tuple:
>>> (0, 1, 2, 3, 4, 5)[:3]
(0, 1, 2)
A string like 'xxx' can also be regarded as a sequence, where each element is a character. Therefore, you can perform slicing operations on strings as well, and the result will still be a string:
>>> 'ABCDEFG'[:3]
'ABC'
>>> 'ABCDEFG'[::2]
'ACEG'
In many programming languages, various substring extraction functions (e.g., substring) are provided for strings. In fact, their purpose is to slice the string. Python does not have dedicated substring extraction functions; it only needs the slicing operation to achieve this, which is very simple.
With slicing operations, loops are no longer needed in many places. Python’s slicing is very flexible, allowing you to achieve in one line what might otherwise require multiple lines of loop code.