Programming and IT
Python: slicing
A slice cuts a piece out of a sequence by the rule "from which index, up to which, with what step". The notation is compact, but it has two places where almost everyone slips: the right bound is not included, and with a negative step the bounds swap places. Let us go through both.
In this article
How to read the notation#
The full form is sequence[start:stop:step]. The start is included, the stop is
not. Any part can be omitted.
=
# [1, 2, 3]
# [0, 1, 2]
# [3, 4, 5]
# [0, 1, 2, 3, 4, 5]
# [0, 2, 4]
The "stop is excluded" rule feels awkward until you notice two consequences: the
length of a slice equals stop - start, and a[:i] and a[i:] together give the
original list with no overlap and no gaps.
= 2
# True
# 3
Negative indexes and a negative step#
A negative index counts from the end: -1 is the last item, -2 the one before
it.
# 5
# [4, 5] the last two
# [0, 1, 2, 3] everything except the last two
A negative step goes from right to left, and then the start must be to the right of the stop:
# [5, 4, 3, 2, 1, 0]
# [4, 3, 2]
# [] — empty: we go left, but the stop is to the right
a[::-1] is the idiomatic way to reverse. Lists also have a reverse() method
that changes the list in place; a slice returns a new one.
Slicing strings#
A string is a sequence too, so the rules are the same, but the result is a string, not a list of characters.
=
# program
# mming
# gnimmargorp
# pgmn
# an empty string
Slicing is handy for cutting fixed-format records: date[:4] is the year in
"2026-09-21", date[5:7] is the month. For variable-length formats split is
more reliable — see the article on Python strings.
A slice as a copy, and assigning to a slice#
a[:] creates a new list with the same items — a shallow copy:
=
# 6 7
Nested objects stay shared, just as with a.copy(). More on that in the article
on Python lists.
You can assign to a slice, and the length of the piece does not have to stay the same:
=
=
# [0, 'a', 'b', 'c', 3, 4]
= # deleting a piece
# ['b', 'c', 3, 4]
del
# ['c', 4]
You cannot do this with strings: they are immutable, and s[0:2] = "ab" raises
TypeError.
Why the result is empty#
A slice never raises IndexError — beyond the bounds it simply returns whatever
is there, down to nothing. That is convenient, but it hides bugs:
# [] no such indexes — empty, no exception
# IndexError: list index out of range
# [] start to the right of stop with step +1
# ValueError: slice step cannot be zero
If a slice is unexpectedly empty, check in order: are the bounds swapped, do you
need a negative step, did you count the stop as inclusive? A quick self-check is
to print len(result) next to the number you expected.
Practice: take a list of twenty numbers and, in one line, get every third item
counting from the end; then split the list into chunks of five with
[a[i:i + 5] for i in range(0, len(a), 5)] — you will need this idiom often.
Step-by-step plan
- Three simple slicesOn a six-item list, get the first three, the last two and a copy of the whole list.
- Step and reversePrint every second item and reverse the sequence with [::-1].
- Negative boundsGet "everything except the last two" and "the last two" and compare with the original length.
- Assign to a sliceReplace two items with three and delete a piece with nums[i:j] = [].
- Split into chunksCut a list of twenty numbers into chunks of five with a list comprehension and a slice.
Start learning this in your own space
The plan goes into your repository: tick off stages, keep notes — the change history shows how far you have come.
Check yourself
1.What is len([0, 1, 2, 3, 4, 5][1:4])?
2.What does print("python"[::-1]) print?
3.What is len([0, 1, 2, 3, 4, 5][3:1])?
4.What does print([0, 1, 2, 3, 4][1:3]) print?
Sources
-
Sequences and slicing in the docsThe table of sequence operations and the rules for boundsfree
-
Python tutorial: lists and stringsA first look at slicing strings and listsfree
-
Glossary: sliceThe exact definition of a slice objectfree
Was this helpful?