Skip to content

Slicing

Python’s slice notation extracts a subsequence from any sequence type — lists, tuples, strings, and bytes.

seq[start : stop : step]
  • start — index of the first element to include (default: 0)
  • stop — index one past the last element to include (default: len(seq))
  • step — stride between elements (default: 1)

Any part can be omitted; Python fills in the default.

nums = [10, 20, 30, 40, 50, 60, 70]
nums[:3] # [10, 20, 30] — first three
nums[2:5] # [30, 40, 50] — indices 2, 3, 4
nums[::2] # [10, 30, 50, 70] — every other element
nums[::-1] # [70, 60, 50, 40, 30, 20, 10] — reversed

Python supports negative indices: -1 is the last element, -2 is second-to-last, and so on.

nums = [10, 20, 30, 40, 50, 60, 70]
nums[-1] # 70 — last element
nums[-3:] # [50, 60, 70] — last three
nums[:-3] # [10, 20, 30, 40] — everything except last three

Negative indices make it easy to access the tail of a sequence without knowing its length.

seq[::-1] is the idiomatic Python way to reverse any sequence. It returns a new reversed object — it does not modify the original.

original = [1, 2, 3, 4, 5]
reversed_copy = original[::-1] # [5, 4, 3, 2, 1]
print(original) # [1, 2, 3, 4, 5] — unchanged

For strings, [::-1] works identically:

s = 'Hello, World!'
print(s[::-1]) # !dlroW ,olleH

seq[:] (no start, stop, or step) returns a shallow copy of the sequence. The new list is a different object but each element still points to the same underlying objects.

original = [1, 2, 3, 4, 5]
copy = original[:]
copy[0] = 99
print(original) # [1, 2, 3, 4, 5] — unchanged
print(copy) # [99, 2, 3, 4, 5]

For nested structures (lists of lists), use copy.deepcopy() instead if you need independent inner lists.

You can store a slice in a variable with slice(start, stop, step) for readability:

HEADER = slice(None, 5)
PAYLOAD = slice(5, -2)
FOOTER = slice(-2, None)
data = b'HDRpayload!FT'
nums = [10, 20, 30, 40, 50, 60, 70]
print('first 3:', nums[:3])
print('last 3:', nums[-3:])
print('middle:', nums[2:5])
print('every other:', nums[::2])
print('reversed:', nums[::-1])
s = 'Hello, World!'
print('first 5:', s[:5])
print('last 6:', s[-6:])
print('every 2nd:', s[::2])
print('reversed:', s[::-1])
original = [1, 2, 3, 4, 5]
copy = original[:]
copy[0] = 99
print('original:', original)
print('copy:', copy)
What does `nums[2:5]` return for `nums = [10, 20, 30, 40, 50, 60, 70]`?
What does `nums[-3:]` return for the same list?
Which slice expression reverses a sequence?
Does `original[:]` create a deep copy or a shallow copy?