Accessing individual characters inside a Python string is one of the first operations you learn after creating strings, and it unlocks the ability to inspect, validate, and transform text one character at a time. Python uses square bracket notation for character access, and the number you put inside the brackets is called an index. The index tells Python which position in the sequence you want, and Python returns the character at that position as a new string of length 1.
The concept is simple, but there are a few rules about how indices work that you need to know to avoid common off-by-one mistakes and runtime IndexError exceptions. This article explains zero-based indexing, the valid range of indices for any string, how negative indices let you count from the end, and how the built-in len() function helps you stay within bounds. If you are new to Python strings, the overview article on Python strings and the article on creating strings provide the foundation that this article builds on.
Once you are comfortable accessing individual characters, the next logical step is extracting groups of characters using slice notation, which is covered in the article on slicing strings in Python. Slicing uses the same indexing rules described here but adds start and stop positions separated by a colon to return substrings instead of single characters.
Zero-based indexing and the valid range
Python counts positions in a string starting from zero, not from one. This means the first character of any non-empty string is at index 0, the second character is at index 1, the third at index 2, and so on. If a string contains n characters, the valid positive indices are the integers from 0 through n minus 1 inclusive. Using any integer outside this range, or using any index on an empty string, raises an IndexError.
This zero-based convention is not unique to Python. It comes from the C language and is shared by Java, JavaScript, Go, Rust, and most other modern languages. The reason is mathematical: when you later learn about slicing, zero-based indexing makes the slice formula cleaner because the length of a slice from index i to index j is simply j minus i. Languages that use one-based indexing require plus-one and minus-one adjustments in the same formulas.
word = "Python"
first = word[0] # 'P'
second = word[1] # 'y'
last = word[5] # 'n'
# word[6] # IndexError: string index out of rangeNotice that the last valid index for the six-character string "Python" is 5, not 6. This is the most common off-by-one error that beginners encounter. Remembering that the valid range goes from 0 to len(text) minus 1, and that len(text) itself is not a valid index, will save you from many debugging sessions.
Python does not have a separate character data type, which is an important difference from languages like Java and C. When you index into a Python string, you get back another string, just one of length 1. This means every string method and operation that works on full-length strings also works on single-character strings without any conversion step, simplifying the language and reducing the number of types you need to think about.
Negative indices for counting from the end
Python supports negative indices as a convenient way to access characters relative to the end of a string without needing to know the string's length upfront. An index of -1 gives you the last character, -2 gives you the second-to-last, -3 the third-to-last, and so on. The valid range of negative indices for a string of length n is from -1 down to -n inclusive.
Negative indices are particularly useful when you want to access the last few characters of a string regardless of how long the string is. For example, checking whether a filename ends with a particular extension, or extracting the last character of user input for validation, can be done with negative indices without calling len() first.
word = "Python"
word[-1] # 'n' (last character)
word[-2] # 'o' (second to last)
word[-3] # 'h' (third to last)
word[-6] # 'P' (first character, same as word[0] or word[-len(word)])The relationship between positive and negative indices is straightforward: for any string s and any valid positive index i, the equivalent negative index is i minus len(s). Conversely, a negative index -k corresponds to the positive index len(s) minus k. Understanding this relationship helps you mentally convert between the two systems and debug indexing issues when they arise.
Using len() to stay within bounds
The built-in len() function returns the number of characters in a string. It is the single most useful tool for avoiding IndexError when working with strings of unknown length, such as user input, lines read from a file, or data received from an API. Before accessing a character at a specific index, you can compare the index against len() to determine whether it is safe. A common pattern writes if len(text) > 0: before accessing text[0], and falls back to a default message when the string is empty.
Calling len() on a string is an O(1) operation in Python, meaning it takes the same amount of time regardless of how long the string is. Python stores the length of each string internally as part of the string object, so len() simply reads that stored value rather than counting characters each time. This means you can use len() freely in loops and conditions without worrying about performance.
Another common pattern is using len() to generate the correct range of indices via range(len(text)) when you need to iterate over every position in a string. While you can iterate over the characters directly with a for loop when you only need the values, accessing by index is necessary when you need to compare characters at specific positions, modify a copy of the string, or track the current position number for display purposes.
Rune AI
Key Insights
- Python string indexing uses square brackets and starts at 0 for the first character.
- Negative indices count backward from the end: -1 is last, -2 is second-last.
- Calling len() returns the number of characters and helps prevent IndexError.
- There is no separate character type; indexing a string returns another string of length 1.
- Out-of-range indices raise IndexError immediately, so validate your index or use slicing for safe access.
Frequently Asked Questions
How do I get the first character of a Python string?
What happens when I use a negative index on a Python string?
Why does Python indexing start at 0 instead of 1?
Conclusion
Accessing individual characters in Python strings is straightforward once you understand zero-based indexing and the valid range of indices for a string of a given length. Positive indices count from the left starting at 0, negative indices count from the right starting at -1, and len() tells you exactly how many characters are available. Always check bounds when working with user input or strings of unknown length to avoid runtime IndexError exceptions.
More in this topic
Create and Assign Variables in Python
Learn every way to create and assign variables in Python, from basic single assignment to expressions, type hints, and practical patterns beginners use every day.
Python Variable Naming Rules
Learn Python's variable naming rules, including allowed characters, reserved keywords, PEP 8 conventions, and how to choose names that make your code readable.
Python Variables Explained
Understand what Python variables are, how they store and reference data, and why Python's variable model is different from other programming languages.