You can slice sequences to create new sequences of the same type containing subsets of the original elements. Slice operations can modify mutable sequences—those that do not modify a sequence work identically for lists, tuples and strings.
Let’s create a slice consisting of the elements at indices 2 through 5 of a list:
In [1]: numbers = [2, 3, 5, 7, 11, 13, 17, 19]
In [2]: numbers[2:6]
Out[2]: [5, 7, 11, 13]
The slice copies elements from the starting index to the left of the colon (2
) up to, but not including, the ending index to the right of the colon (6
). The original list is not modified.
If you omit the starting index, 0
is assumed. So, the slice numbers[:6]
is equivalent to the slice numbers[0:6]
:
In [3]: numbers[:6]
Out[3]: [2, 3, 5, 7, 11, 13]
In [4]: numbers[0:6]
Out[4]: [2, 3, 5, 7, 11, 13]
If you omit the ending index, Python assumes the sequence’s length (8
here), so snippet [5]
’s slice contains the elements of numbers
at indices 6
and 7
:
In [5]: numbers[6:]
Out[5]: [17, 19]
In [6]: numbers[6:len(numbers)]
Out[6]: [17, 19]
Omitting both the start and end indices copies the entire sequence:
In [7]: numbers[:]
Out[7]: [2, 3, 5, 7, 11, 13, 17, 19]
Though slices create new objects, slices make shallow copies of the elements—that is, they copy the elements’ references but not the objects they point to. So, in the snippet above, the new list’s elements refer to the same objects as the original list’s elements, rather than to separate copies. In the “Array-Oriented Programming with NumPy” chapter, we’ll explain deep copying, which actually copies the referenced objects themselves, and we’ll point out when deep copying is preferred.
The following code uses a step of 2
to create a slice with every other element of numbers
:
In [8]: numbers[::2]
Out[8]: [2, 5, 11, 17]
We omitted the start and end indices, so 0
and len(numbers)
are assumed, respectively.
You can use a negative step to select slices in reverse order. The following code concisely creates a new list in reverse order:
In [9]: numbers[::-1]
Out[9]: [19, 17, 13, 11, 7, 5, 3, 2]
This is equivalent to:
In [10]: numbers[-1:-9:-1]
Out[10]: [19, 17, 13, 11, 7, 5, 3, 2]
You can modify a list by assigning to a slice of it—the rest of the list is unchanged. The following code replaces numbers
’ first three elements, leaving the rest unchanged:
In [11]: numbers[0:3] = ['two', 'three', 'five']
In [12]: numbers
Out[12]: ['two', 'three', 'five', 7, 11, 13, 17, 19]
The following deletes only the first three elements of numbers
by assigning an empty list to the three-element slice:
In [13]: numbers[0:3] = []
In [14]: numbers
Out[14]: [7, 11, 13, 17, 19]
The following assigns a list’s elements to a slice of every other element of numbers
:
In [15]: numbers = [2, 3, 5, 7, 11, 13, 17, 19]
In [16]: numbers[::2] = [100, 100, 100, 100]
In [17]: numbers
Out[17]: [100, 3, 100, 7, 100, 13, 100, 19]
In [18]: id(numbers)
Out[18]: 4434456648
Let’s delete all the elements in numbers
, leaving the existing list empty:
In [19]: numbers[:] = []
In [20]: numbers
Out[20]: []
In [21]: id(numbers)
Out[21]: 4434456648
Deleting numbers
’ contents (snippet [19]
) is different from assigning numbers
a new empty list []
(snippet [22]
). To prove this, we display numbers
’ identity after each operation. The identities are different, so they represent separate objects in memory:
In [22]: numbers = []
In [23]: numbers
Out[23]: []
In [24]: id(numbers)
Out[24]: 4406030920
(True/False) Slice operations that modify a sequence work identically for lists, tuples and strings.
Answer: False. Slice operations that do not modify a sequence work identically for lists, tuples and strings.
(Fill-In) Assume you have a list called names
. The slice expression _____ creates a new list with the elements of names
in reverse order.
Answer: names[::-1]
(IPython Session) Create a list called numbers
containing the values from 1
through 15
, then use slices to perform the following operations consecutively:
Select number
’s even integers.
Replace the elements at indices 5
through 9
with 0
s, then show the resulting list.
Keep only the first five elements, then show the resulting list.
Delete all the remaining elements by assigning to a slice. Show the resulting list.
Answer:
In [1]: numbers = list(range(1, 16))
In [2]: numbers
Out[2]: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
In [3]: numbers[1:len(numbers):2]
Out[3]: [2, 4, 6, 8, 10, 12, 14]
In [4]: numbers[5:10] = [0] * len(numbers[5:10])
In [5]: numbers
Out[5]: [1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 11, 12, 13, 14, 15]
In [6]: numbers[5:] = []
In [7]: numbers
Out[7]: [1, 2, 3, 4, 5]
In [8]: numbers[:] = []
In [9]: numbers
Out[9]: []
Recall that multiplying a sequence repeats that sequence the specified number of times.
3.146.255.127