Access Individual Characters and Substrings in Python
Learn how Python strings use zero-based indexing and slicing to retrieve individual characters and ranges of characters.
A Python string is an ordered sequence of text characters. A character is one unit in that sequence: a letter, digit, punctuation mark, or whitespace character such as a space.
For example, the string "Hello world!" contains 12 characters. Every character has a numeric index, which is the position used to access it.
Before continuing, you should understand Python strings, variables, string literals, and print().
Character Positions in a String
Python uses zero-based indexing. This means the first character has index 0, the second has index 1, and so on.
| Character | Positive index | Negative index | Notes |
|---|---|---|---|
H | 0 | -12 | First character |
e | 1 | -11 | Second character |
l | 2 | -10 | Letter |
l | 3 | -9 | Letter |
o | 4 | -8 | Letter |
| 5 | -7 | Space; whitespace counts |
w | 6 | -6 | Letter after the space |
o | 7 | -5 | Letter |
r | 8 | -4 | Letter |
l | 9 | -3 | Letter |
d | 10 | -2 | Letter |
! | 11 | -1 | Final punctuation character |
The space between Hello and world! occupies index 5. Therefore, w is at index 6, not index 5. Punctuation also occupies a position, so the exclamation mark has index 11.
Retrieve One Character with Indexing
To retrieve one character, put an index in square brackets after a string variable. Square brackets are the [ ] syntax used for indexing and slicing sequences.
new_string = "Hello world!"
print(new_string[0])
print(new_string[6])
Output:
H
w
The expression new_string[0] retrieves the first character. The expression new_string[6] retrieves the w.
Indexing Versus Slicing
Indexing uses one position and retrieves one character. Slicing uses a range and retrieves a new string containing zero or more characters.
| Expression form | Meaning | Example | Result |
|---|---|---|---|
string[index] | Retrieve one character | new_string[0] | H |
string[start:end] | Retrieve a range from start through the position before end | new_string[0:3] | Hello portion: Hel |
string[:end] | Start at the beginning and stop before end | new_string[:5] | Hello |
string[start:] | Start at start and continue to the end | new_string[5:] | world! |
string[-1] | Retrieve the final character | new_string[-1] | ! |
String Slicing with Start and End Indexes
A slice is a selected range of characters. Its basic syntax is string[start:end].
- The start index is the first included position.
- The end index is the first excluded position.
For example:
new_string = "Hello world!"
print(new_string[0:3])
Output:
Hel
Indexes 0, 1, and 2 are included. Index 3 is excluded. A useful way to choose an end index is to place it one position after the final character you want.
Omit Slice Boundaries
You can omit a boundary when you want to slice from the beginning or through the end.
Slice from the beginning
In string[:end], the missing start index means “start at the beginning.”
new_string = "Hello world!"
print(new_string[:5])
Output:
Hello
This includes indexes 0 through 4. Index 5 is excluded.
Slice through the end
In string[start:], the missing end index means “continue through the final character.”
new_string = "Hello world!"
print(new_string[5:])
Output:
world!
Because the start index is included, the space at index 5 appears in the result. To exclude that space, use new_string[6:].
Negative Indexing
A negative index counts backward from the right end of a string. The index -1 always refers to the final character, -2 refers to the character before it, and so on.
new_string = "Hello world!"
print(new_string[-1])
Output:
!
Negative indexing is useful when you need a character near the end without calculating the string's final positive index.
Common Mistakes and Troubleshooting
Using index 1 for the first character
Python uses zero-based indexing, so index 1 refers to the second character. Use index 0 for the first character.
Forgetting whitespace or punctuation
A space is a character, even though it is not visible in ordinary output. Punctuation is also a character. Count every character when determining an index.
Expecting the end index to be included
The end boundary of a slice is excluded. For example, new_string[0:3] returns "Hel", not "Hell". Increase the end index by one if the next character should be included.
Using a nonexistent single-character index
An indexing expression must refer to an existing position. An index outside the string raises an IndexError. Check the string's length and valid indexes before using a single index.
Slices behave more flexibly: an out-of-range slice boundary can produce the available characters or an empty string instead of raising an error. However, you should still choose boundaries carefully so the result matches your intention.
Practice Summary
new_string = "Hello world!"
print(new_string[0]) # H
print(new_string[6]) # w
print(new_string[0:3]) # Hel
print(new_string[:5]) # Hello
print(new_string[5:]) # world!
print(new_string[-1]) # !
Once you can identify character positions, you can combine indexing and slicing with other string functions and escape characters.