String Slicing
Concepts covered: Slicing
Slicing pulls out a run of characters in one step. text[start:stop] returns a new string holding the characters from index start up to, but not including, index stop. When both bounds fall inside the string, the result has stop - start characters.
text = "Python Programming"
print(text[0:6])
print(text[7:18])Python Programming
text[0:6] takes positions 0 through 5, the 6 letters of Python. text[7:18] takes positions 7 through 17, the 11 letters of Programming; index 6, the space, belongs to neither slice. Because stop is excluded, 2 slices that share a boundary fit together with nothing lost and nothing doubled: text[0:7] + text[7:18] rebuilds all 18 characters.
Leaving out an end
Leave out start and the slice begins at 0; leave out stop and it runs to the end. text[:n] is the first n characters, text[n:] is the rest, and text[:n] + text[n:] equals text for every n. In an ISO timestamp such as ts = "2024-03-15T08:42:10Z", each field sits at a fixed position, so a slice reads it with no searching at all.
| Slice of ts | Result | What it holds |
|---|---|---|
| ts[:4] | 2024 | year |
| ts[5:7] | 03 | month |
| ts[8:10] | 15 | day |
| ts[:10] | 2024-03-15 | date part |
| ts[11:19] | 08:42:10 | time part |
| ts[11:13] | 08 | hour |
| ts[-1:] | Z | time-zone marker |
Negative bounds and bounds past the end
filename = "events_2024-03-15.csv"
print(filename[-4:])
print(filename[:-4])
print(filename[7:17])
print(filename[18:99])
print(filename[99:])
print(len(filename[99:]))Output:
.csv events_2024-03-15 2024-03-15 csv 0
filename[-4:] starts 4 characters from the end, so it reads the extension however long the name is, and filename[:-4] keeps everything else. The last 3 lines show where slicing parts ways with indexing: a bound past the end is clamped to the length. filename[18:99] stops at the real end, and filename[99:] is an empty string of length 0, printed as a blank line. Clamping makes slices safe on short input and also silent: slicing [:10] from a 6-character value returns 6 characters without complaint, so check len() whenever the width matters.
What does this program print?
tag = "v2.14.3"
print(tag[1:-2] + "|" + tag[:1] + "|" + tag[3:5])- 2.14|v|14
- 2.14.|v|14
- 2.14|v2|14
- 2.14|v|14.
- Indexing s[i]
- Returns exactly 1 character, as a string
- A position past the end raises IndexError
- s[len(s)] crashes
- On "", every index fails
- Slicing s[a:b]
- Returns a string of 0 or more characters
- Bounds past the end are clamped to the length
- s[len(s):] returns ""
- On "", every slice returns ""
A third number: the step
digits = "0123456789"
print(digits[::2])
print(digits[1::2])
print(digits[::-1])
print(digits[7:2:-1])
print(len(digits[2:7:-1]))Output:
02468 13579 9876543210 76543 0
The third number is the step, how far to move between characters. A step of 2 takes every second character: starting at 0 that gives the even digits, starting at 1 the odd ones. A negative step walks right to left, so [::-1] returns the string reversed. With a negative step, start must sit to the right of stop: digits[7:2:-1] reads positions 7 down to 3 and stops before 2, while digits[2:7:-1] points the wrong way and comes back empty.
Bounds never raise, but a step of 0 would never move, so Python refuses it: digits[::0] raises ValueError: slice step cannot be zero.
Building a new string from slices
Slices are pieces, and + joins them back in a new order or with text added between them. Inserting new at position i is s[:i] + new + s[i:], so a compact date such as "20240315" becomes the dashed form with 2 inserts:
compact = "20240315"
iso = compact[:4] + "-" + compact[4:6] + "-" + compact[6:]
print(iso)
print(len(compact), len(iso))
print(len(compact[3:3]))Output:
2024-03-15 8 10 0
The first slice covers positions 0 to 3. Each later slice starts where the previous one stopped, at 4 and then at 6, and the last ends at 7, so no digit is lost or repeated. The result grows from 8 characters to 10, 1 per dash. A slice whose start equals its stop, such as compact[3:3], holds nothing: it marks the gap between 2 characters, which is where an insert lands.
About this lesson
This section is part of the Strings: Intermediate lesson on DataDriven, the home of data engineering. Lessons cover SQL, Python, Spark, data modeling and pipeline architecture, and each section pairs its explanation with worked examples and practice you run as you go.