How to Slice a List in Python
If you’re wondering how list slicing works in Python, the short answer is to use seq[start:stop:step] with 0-based indices and an exclusive stop by delmiting the start and stop indexes with a colon (:).
Problem
- You want to extract parts of a list without looping.
- You need clear
start:stop:steprules, negative indices, and common slice recipes.
Here’s the same content, reordered from simplest to more advanced:
Solutions
You generally just use the list[start:end] convention when slicing lists (often called “arrays” in other languages) in Python.
Python List Slicing (Basics)
Slicing uses seq[start:stop:step]. stop is exclusive. Any part may be omitted.
nums = [0, 1, 2, 3, 4, 5, 6]
nums[2:5] # [2, 3, 4]
nums[:3] # [0, 1, 2] (from start)
nums[4:] # [4, 5, 6] (to end)
nums[::2] # [0, 2, 4, 6] (step = 2)
nums[::-1] # [6, 5, 4, 3, 2, 1, 0] (reverse)
Slicing Lists Python (Negative Indices)
Negative indices count from the end.
letters = ["a", "b", "c", "d", "e"]
letters[-3:] # ['c', 'd', 'e']
letters[:-2] # ['a', 'b', 'c']
letters[-4:-1] # ['b', 'c', 'd']
How to Slice Last Element of List Python
Use a one-element tail slice or get the last n items.
items = [10, 20, 30, 40]
items[-1:] # [40] (slice result is a list)
items[-2:] # [30, 40]
Python List Slice (Stride and Reverse)
Use step for strides and -1 to reverse.
data = list(range(10)) # [0..9]
data[1:9:3] # [1, 4, 7]
data[::-1] # reversed list
Python Slicing (Slice Assignment)
Slice assignment can replace ranges in place.
nums = [0, 1, 2, 3, 4]
nums[1:4] = [10, 11] # [0, 10, 11, 4]
nums[:2] = [] # deletes first two elements -> [11, 4]
nums[:] = [9, 9] # replace entire list -> [9, 9]
String Slicing in Python
Strings use the same slicing rules.
s = "abcdef"
s[2:5] # 'cde'
s[::-1] # 'fedcba'
Slice of Tuple in Python Example (Python Slice Tuple)
Tuples also support slicing (tuples are immutable; slice returns a new tuple).
t = (0, 1, 2, 3, 4)
t[1:4] # (1, 2, 3)
t[::-1] # (4, 3, 2, 1, 0)
Things to Consider
- Slices return new objects; lists/strings produce copies, not views.
stopis exclusive; off-by-one mistakes are common.- Out-of-range indices are clamped; no
IndexErrorfrom slicing. stepcannot be0(raisesValueError).- Negative
stepreverses direction; default bounds differ with-1. - Slice assignment can change list length.
Splitting a List in Half with Variables
You can calculate slice indices at runtime with variables instead of int literals.
For example, split a list into two halves:
nums = list(range(10)) # [0..9]
mid = len(nums) // 2
left = nums[:mid]
right = nums[mid:]
print(left) # [0, 1, 2, 3, 4]
print(right) # [5, 6, 7, 8, 9]
NOTE: The
//operator in Python is floor division. It always returns an integer, even if the list length is odd. For example,9 // 2evaluates to4, not4.5. That means your slices will still work without error — the halves will just differ in size by one element if the list length is odd.
This pattern is useful for dynamic slicing (e.g., splitting batches, chunking data, etc.).
Python Combining Lists
Concatenate with + or extend via slice assignment.
a = [1, 2]; b = [3, 4]
a + b # [1, 2, 3, 4]
a[len(a):] = b # a becomes [1, 2, 3, 4]
Remove Duplicate From List Python
Slicing does not deduplicate. Use dict.fromkeys or a set if order rules allow.
vals = [1, 2, 2, 3, 1]
list(dict.fromkeys(vals)) # preserves first occurrence order -> [1, 2, 3]
Gotchas
- Slicing is copy-based for lists/strings; large slices duplicate memory.
seq[start:end]excludesend(the stop or end index); useend+1if you need to include it.seq[-1]is the last element;seq[-1:]is a one-element list.step=0is invalid.- Do not assign variables named after built-in types (
list,dict,str, etc.) — it overwrites them and breaks built-in functionality. - With negative steps, default bounds differ:
seq[::-1]is the full reverse. - Iterators/generators do not support slicing directly; use
itertools.islice.
Python Slice Range
Out-of-range slices do not raise errors. Python “clamps” slice indices to valid bounds:
my_list = [1, 2, 3, 4]
print(my_list[2:999]) # [3, 4]
Contrast with direct indexing, which raises IndexError:
print(my_list[999]) # IndexError
Python Check If List Is Empty
Check emptiness directly; do not rely on slices:
lst = []
if not lst:
print("empty")
Or you can use len(lst) if you need to know exactly how many elements are in the list to begin with.
Sources
- Official Documentation (Common Sequence Operations)
- Relevant StackOverflow Answer
- GeeksforGeeks: Python List Slicing
- Python Central: Slice Lists/Arrays/Tuples
- Reddit r/learnprogramming: slice.indices
- Python Docs: Sequence Types
Further Investigation
sliceobjects:slice(start, stop, step)and reusability.itertools.islicefor iterators/generators.- NumPy slicing (views vs copies), pandas
.loc/.ilocsemantics. - Memory considerations for large slices and copies.
TL;DR
Use seq[start:stop:step] to slice; stop is exclusive, indices clamp, and step can be negative.
nums = [0, 1, 2, 3, 4, 5, 6]
head = nums[:3] # [0, 1, 2]
tail = nums[-2:] # [5, 6]
middle = nums[2:5] # [2, 3, 4]
stride = nums[::2] # [0, 2, 4, 6]
rev = nums[::-1] # [6, 5, 4, 3, 2, 1, 0]