- 5.1 Introduction
- 5.2 Lists
- 5.3 Tuples
- 5.4 Unpacking Sequences
- 5.5 Sequence Slicing
- 5.6 del Statement
- 5.7 Passing Lists to Functions
- 5.8 Sorting Lists
- 5.9 Searching Sequences
- 5.10 Other List Methods
- 5.11 Simulating Stacks with Lists
- 5.12 List Comprehensions
- 5.13 Generator Expressions
- 5.14 Filter, Map and Reduce
- 5.15 Other Sequence Processing Functions
- 5.16 Two-Dimensional Lists
- 5.17 Intro to Data Science: Simulation and Static Visualizations
- 5.18 Wrap-Up
5.5 Sequence Slicing
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.
Specifying a Slice with Starting and Ending Indices
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.
Specifying a Slice with Only an Ending Index
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]
Specifying a Slice with Only a Starting Index
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]
Specifying a Slice with No Indices
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.
Slicing with Steps
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.
Slicing with Negative Indices and Steps
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]
Modifying Lists Via Slices
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
When you assign a new object to a variable (as in snippet [21]), the original object will be garbage collected if no other variables refer to it.