To remove a character from a Python string, choose the rule first. To remove the character at a known position, slice the string on both sides of that position and join the pieces: s[:i] + s[i+1:]. To remove a character by its value, call s.replace() with an empty replacement, passing a count of 1 to remove only the first match. Python strings cannot be edited in place, so every method below returns a new string, and the original is unchanged.
Why removal always creates a new string
A Python str is immutable. Assignment such as s[i] = '' raises a TypeError, because individual characters cannot be replaced inside an existing string. Slicing, replace(), and translate() all build and return a new string. If you need to keep the result, assign it back to a name:
text = "banana"
text = text[:2] + text[3:] # text is now "baana"
Reassigning to the same name is the usual pattern. Keeping the original is also simple, because the first value is still available until you overwrite it.
Remove a character by index
Use an index when you know the position. Python indexes strings from zero, so the first character is at index 0, and the last is at len(s) - 1.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
#1 Best Overall
The slicing formula
The expression s[:i] + s[i+1:] takes everything before position i, skips the character at i, and joins everything after it:
text = "banana"
index = 2
without_at_index = text[:index] + text[index + 1:] # "baana"
Negative indices and the trap at -1
Negative indices count from the end, so -1 is the last character and -2 is the one before it. Using s[:-1] on its own removes the final character. The general formula, however, behaves differently when the index is negative. With i = -1, the second slice becomes s[0:], which is the whole string, so the result duplicates content:
Rank #2
s = "abcd"
i = -1
s[:i] + s[i+1:] # "abc" + "abcd" == "abcabcd" (wrong)
Convert negative positions to their positive equivalents before slicing:
if i < 0:
i += len(s)
result = s[:i] + s[i+1:] # "abc" for i = -1
Out-of-range positions
Slices clip out-of-range bounds silently, so the formula does not raise an error for an index past the end. For "abc" and i = 10, s[:10] returns "abc" and s[11:] returns "", so the result is an unchanged "abc". Direct indexing such as s[10] raises IndexError. If an invalid position should be reported instead of ignored, validate it first:
Free tools Windows power users keep installed
One-click scans. No signup required.
def remove_at(s, i):
if not -len(s) <= i < len(s):
raise IndexError(f"index {i} is out of range for length {len(s)}")
if i < 0:
i += len(s)
return s[:i] + s[i+1:]
Remove a character by value
Use str.replace(old, new, count) when you know the character or substring but not its position. Replacing with an empty string deletes the match.
Remove the first occurrence
Pass 1 as the count to limit the replacement to the first match:
text = "banana"
text.replace("a", "", 1) # "bnana"
Remove every occurrence
Omit the count, and replace() removes all matches:
text.replace("a", "") # "bnn"
When the value is absent
If the value does not occur, replace() returns an unchanged copy and raises no error. Check with in first only if you need to know whether a removal happened.
Remove any of several characters
When you want to delete a set of characters wherever they appear, str.translate() is more direct than chaining several replace() calls. It takes a translation table, which str.maketrans() builds. Mapping a character to None deletes it.
Best Value
Deleting characters
table = str.maketrans({"-": None, "_": None})
cleaned = "a-b_c".translate(table) # "abc"
Replacing characters instead of deleting them
A two-string call to str.maketrans() maps each character to another character, not to nothing. The following example converts separators to spaces, so nothing is removed:
table = str.maketrans("-_", " ")
"a-b_c".translate(table) # "a b c"
Confusing the two forms is a common error. Use the dictionary form with None values when you want deletion.
Choosing a method
| Need | Method | Behavior |
|---|---|---|
| Remove the character at one position | s[:i] + s[i+1:] |
Position-based. Returns a new string. Out-of-range positions are clipped by slicing and produce no change; direct indexing raises IndexError. Negative indices need normalizing first. |
| Remove the first matching substring | s.replace(value, '', 1) |
Value-based. Only the first match is removed. An absent value leaves the string unchanged. |
| Remove every matching substring | s.replace(value, '') |
Value-based. Every occurrence is removed. An absent value leaves the string unchanged. |
| Remove any character from a set | s.translate(str.maketrans({char: None, ...})) |
Character-based. Each listed character is deleted wherever it occurs. |
Unicode caveat: code points are not always visible symbols
Python indexes strings by Unicode code points. Some visible symbols, such as accented letters written with a combining mark or certain emoji sequences, are built from several code points. Removing one index can therefore remove only part of what a reader sees as a single character. The string "é" displays as one accented é but has two code points, so s[:1] + s[2:] leaves a bare e. If your input may contain such text, decide whether code-point removal is acceptable or whether you need grapheme-aware handling from a dedicated library.
Version notes
Indexing, slicing, str.replace(), and str.translate() with str.maketrans() are long-standing parts of Python 3 and are documented in the official tutorial and the built-in types reference. The examples above use only these features, so they should run unchanged on current Python 3 releases. The Python version your project targets is still the authority for any version-specific behavior.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →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.




