iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To remove a character from a Python string, you build a new string rather than editing the original. Remove a character at a known position with s[:i] + s[i+1:]. Remove a character by its value with s.replace(char, '', 1) for the first match or s.replace(char, '') for every match. Each method returns a new string, so you must assign the result to a variable to keep it.
Why you cannot delete a character in place
Python str objects are immutable. Item assignment such as s[0] = '' raises a TypeError, and no string method modifies the original object. Slicing and methods such as replace() and translate() always produce a result string. The examples below therefore follow the pattern result = ..., and the original value stays unchanged.
Remove a character by index
Use slicing when you know the position. A slice from the start up to the index, joined to a slice from one position after the index, skips exactly the character at that index:
Recommended Free Tools
text = "banana"
index = 2
without_at_index = text[:index] + text[index + 1:] # "baana"
Indexes start at zero, so index 2 is the third character, the n in banana. The left slice text[:2] gives "ba", and the right slice text[3:] gives "ana".
#1 Best Overall
Watch for out-of-range and negative indexes
The slice formula and direct indexing behave differently at the edges, and the difference matters when you accept user input:
- Out-of-range index with slicing fails silently.
"abc"[:10] + "abc"[11:]returns"abc"unchanged. Slices clip bounds instead of raising an error. - Out-of-range index with direct access raises an error.
"abc"[10]raisesIndexError. - Negative indexes break the slice formula. For
s = "abc"andi = -1,s[:-1] + s[0:]returns"ababc", not"ab", becauses[i+1:]becomess[0:]. Normalize the index before slicing. - Empty strings return empty results.
""[:0] + ""[1:]returns"", so the formula never fails on an empty string.
If an invalid position should be reported rather than ignored, wrap the logic in a helper that normalizes negative indexes and checks bounds:
Rank #2
def remove_at(s, i):
if i < 0:
i += len(s)
if not 0 <= i < len(s):
raise IndexError("string index out of range")
return s[:i] + s[i+1:]
remove_at("banana", 2) # "baana"
remove_at("abc", -1) # "ab"
remove_at("abc", 10) # raises IndexError
Remove a character by value
str.replace(old, new, count) removes substrings by value. Pass an empty string as new to delete matches. The optional count argument limits how many matches are replaced, counting from the left.
Free tools Windows power users keep installed
One-click scans. No signup required.
Remove only the first occurrence
Pass 1 as the third argument to delete only the first match:
text = "banana"
without_first_a = text.replace("a", "", 1) # "bnana"
Remove every occurrence
Omit the count to delete all matches:
text = "banana"
without_all_a = text.replace("a", "") # "bnn"
The value does not have to be one character. "banana".replace("ana", "") returns "bn", because replace() matches substrings. If the value is not present, the call returns the original text unchanged rather than raising an error.
Remove any character from a set with translate()
When you need to delete several different characters in one pass, str.translate() applies a mapping table to every character. Build the table with str.maketrans(). A dictionary whose values are None marks characters for deletion:
table = str.maketrans({"-": None, "_": None})
cleaned = "a-b_c".translate(table) # "abc"
Do not confuse deletion with replacement. Mapping characters to a string instead of None substitutes them rather than removing them. The two-string form of maketrans() replaces every character in the first string with the matching character in the second:
table = str.maketrans("-_", " ")
"a-b_c".translate(table) # "a b c"
Unlike replace(), translate() has no count argument. Every matching character is affected.
Best Value
Choosing a method
| Need | Method | Selection rule | Behavior to know |
|---|---|---|---|
| Remove one character at a known position | s[:i] + s[i+1:] |
Position | Returns a new string. Slicing clips out-of-range bounds silently; normalize negative indexes first. |
| Remove the first matching substring | s.replace(value, '', 1) |
Value (substring) | Only the first match is removed. An absent value leaves the string unchanged. |
| Remove every matching substring | s.replace(value, '') |
Value (substring) | All matches are removed. An absent value leaves the string unchanged. |
| Remove any character from a set | s.translate(str.maketrans({char: None, ...})) |
Character set | Every matching character is deleted. There is no count limit. |
Unicode caveat: an index is a code point, not always a visible symbol
Python indexes strings by Unicode code points. A character a reader sees on screen can be built from more than one code point, so removing a single index does not always remove a whole visible symbol. For example, "café" written with a combining accent is five code points, not four:
decomposed = "café" # displays as "café", length 5
decomposed[:3] + decomposed[4:] # "caf" plus the bare accent, which attaches to the "f"
If your input may contain accented letters, emoji with modifiers, or combined characters, normalize the text first with the unicodedata module or remove by visible characters after you have confirmed the input format.
Version notes
The slicing, replace(), and translate() behavior described here is documented in the official Python tutorial (3.14 documentation) and the built-in types reference (3.12 documentation). These operations have been part of Python 3 for many years, so the code above works across current Python 3 releases. Check the version your project targets if you rely on newer standard-library features.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

