Lesson 6.3: Slicing and Indexing
By the end of this lesson, you will be able to:
- Use slice syntax [start:stop:step] to extract sublists
- Omit start, stop, or step values for common patterns
- Copy lists safely using slicing
- Reverse lists using slice notation
- Combine slicing with negative indexes
What is Slicing?
list[start:stop:step]. The result is a new list containing the selected elements.
While indexing gives you a single element, slicing gives you a range of elements. Think of it like cutting a section from a loaf of bread -- you specify where to start cutting and where to stop.
Basic Slice Syntax
numbers = [10, 20, 30, 40, 50, 60, 70] # 0 1 2 3 4 5 6 # Get elements from index 1 to 4 (not including 4) subset = numbers[1:4] print(subset) # Get elements from index 2 to 6 print(numbers[2:6])
Key Rule: Stop Index is Exclusive
The slice [start:stop] includes the element at start but does NOT include the element at stop. This is the same as how range() works.
Omitting Start, Stop, or Step
You can omit any of the three values, and Python will use defaults:
- Omit
start: defaults to the beginning (index 0) - Omit
stop: defaults to the end of the list - Omit
step: defaults to 1
numbers = [10, 20, 30, 40, 50, 60, 70] # From beginning to index 3 print(numbers[:3]) # From index 4 to the end print(numbers[4:]) # Get the entire list (copy) print(numbers[:]) # First three elements print(numbers[:3]) # Last three elements print(numbers[-3:])
Using the Step Parameter
The third value in the slice specifies the step -- how many elements to skip between each selected element.
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # Every other element print(numbers[::2]) # Every third element print(numbers[::3]) # Every other element from index 1 to 8 print(numbers[1:8:2])
Practical Example: Extracting Even and Odd Positioned Items
students = ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank"] # Students at even indexes (0, 2, 4) team_a = students[::2] print("Team A:", team_a) # Students at odd indexes (1, 3, 5) team_b = students[1::2] print("Team B:", team_b)
Reversing with Slicing
Using a step of -1 reverses the list. This creates a new reversed list without modifying the original.
numbers = [1, 2, 3, 4, 5] # Reverse the list reversed_nums = numbers[::-1] print("Reversed:", reversed_nums) print("Original:", numbers) # Original unchanged
Negative Step with Start and Stop
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # From index 7 down to index 2 (not including 2) print(numbers[7:2:-1]) # Every other element in reverse print(numbers[::-2])
Copying Lists Safely
.copy() to make a true copy.
# This does NOT copy the list! original = [1, 2, 3] not_a_copy = original # Both point to same list not_a_copy.append(4) print("Original:", original) # Original is also changed! print("Not a copy:", not_a_copy)
# Use slicing to create a true copy original = [1, 2, 3] copy1 = original[:] # Slice copy copy2 = original.copy() # .copy() method copy1.append(99) print("Original:", original) # Unchanged! print("Copy 1:", copy1) print("Copy 2:", copy2)
Try It Yourself
Create a list data = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100]. Using slicing, extract: (1) the first five elements, (2) the last three elements, (3) every third element, and (4) the list in reverse.
Slicing with Negative Indexes
You can mix positive and negative indexes in slices for flexible data extraction.
letters = ["a", "b", "c", "d", "e", "f", "g"] # Everything except the first and last print(letters[1:-1]) # Last four elements print(letters[-4:]) # Everything except the last two print(letters[:-2])
Slicing Never Causes IndexError
Unlike individual indexing, slicing gracefully handles out-of-range values. It simply returns what is available.
short = [1, 2, 3] print(short[0:100]) # No error, returns all elements print(short[10:20]) # No error, returns empty list
Check Your Understanding
Given: data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- What does
data[2:5]return? - What does
data[::3]return? - What does
data[::-1]return? - How do you copy a list using slicing?
[2, 3, 4](from index 2 up to but not including 5)[0, 3, 6, 9](every third element)[9, 8, 7, 6, 5, 4, 3, 2, 1, 0](reversed)copy = data[:](slice with no start or stop)
Key Takeaways
- Slice syntax:
list[start:stop:step]-- stop is exclusive - Omit start/stop/step to use defaults (beginning, end, 1)
- Use
[::-1]to reverse a list without modifying the original - Use
[:]to create a shallow copy of a list - Slicing returns a new list and never raises IndexError
- Assigning a list to a new variable does NOT copy it -- both point to the same data