Here’s a detailed breakdown of Python slicing, including mechanics, edge cases, and advanced examples:
1. Slicing Syntax
sequence[start : stop : step]
- All parameters are optional:
start
(default0
),stop
(defaultlen(sequence)
), andstep
(default1
). - Returns a new sequence (original remains unmodified).
- Works with lists, strings, tuples, bytes, and NumPy arrays.
2. Parameter Behavior
Parameter | Description |
---|---|
start | Inclusive starting index (use None to default to 0 ). |
stop | Exclusive ending index (use None to default to end of sequence). |
step | Interval between elements. If negative, iterates backward. |
3. Key Concepts
A. Negative Indices
-1
= last element,-2
= second last, etc.
my_list = [0, 1, 2, 3, 4]
print(my_list[-3:]) # Last 3 elements → [2, 3, 4]
B. Negative Step
- When
step < 0
, the slice starts fromstart
and moves backward.
my_list = [0, 1, 2, 3, 4]
print(my_list[3:0:-1]) # From index 3 to 1 (exclusive) → [3, 2, 1]
C. Out-of-Bounds Handling
- Python silently adjusts out-of-range indices:
my_list = [0, 1, 2]
print(my_list[0:10]) # → [0, 1, 2]
4. Detailed Examples
Example 1: Basic Slicing
text = "abcdefgh"
print(text[2:5]) # "cde" (indices 2, 3, 4)
print(text[:4]) # "abcd" (start=0, stop=4)
print(text[3:]) # "defgh" (start=3 to end)
Example 2: Step Size
nums = [0, 1, 2, 3, 4, 5, 6]
print(nums[::2]) # [0, 2, 4, 6] (every 2nd element)
print(nums[1::3]) # [1, 4] (start=1, step=3)
print(nums[::-1]) # [6, 5, 4, 3, 2, 1, 0] (reverse)
Example 3: Negative Indices + Step
data = [10, 20, 30, 40, 50]
print(data[-2::-1]) # From index -2 (40) backward: [40, 30, 20, 10]
print(data[-1:2:-1]) # From -1 (50) to index 3 (exclusive): [50, 40]
Example 4: Modifying Lists with Slices
my_list = [0, 1, 2, 3, 4]
my_list[1:3] = [10, 20] # Replace indices 1-2 → [0, 10, 20, 3, 4]
my_list[::2] = [5, 15, 25] # Assign to even indices → [5, 10, 15, 3, 25]
del my_list[2:4] # Delete elements 2-3 → [5, 10, 25]
Example 5: Strings and Tuples
s = "hello"
print(s[1:4:2]) # "el" → indices 1 ('e') and 3 ('l')
t = (0, 1, 2, 3)
print(t[-2:]) # (2, 3)
5. Advanced Use Cases
A. Slice Objects
Create reusable slices:
even_slice = slice(None, None, 2) # Equivalent to [::2]
print(my_list[even_slice]) # Get even-indexed elements
B. Multi-Dimensional Slicing (e.g., NumPy)
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr[:, 1]) # Get second column → [2, 5, 8]
C. Edge Cases
empty_list = []
print(empty_list[:3]) # → [] (no error)
my_str = "abc"
print(my_str[5:]) # → "" (empty string)
6. Key Takeaways
- Slicing does not mutate the original sequence.
sequence[::-1]
is a common idiom to reverse sequences.- Use
del sequence[a:b]
to delete a slice. - Slices handle out-of-bounds indices gracefully.
7. Common Pitfalls
- Reversing with
step=-1
:
# To reverse the entire list:
my_list = [1, 2, 3]
reversed_list = my_list[::-1] # Correct → [3, 2, 1]
partial_reverse = my_list[2:0:-1] # → [3, 2] (stops before index 0)
- Empty slices when
start >= stop
(with positivestep
):
print(my_list[3:1]) # → []
Let me know if you’d like to explore a specific scenario!