75

How can I replace a character in a string from a certain index? For example, I want to get the middle character from a string, like abc, and if the character is not equal to the character the user specifies, then I want to replace it.

Something like this maybe?

middle = ? # (I don't know how to get the middle of a string)

if str[middle] != char:
    str[middle].replace('')
codeforester
  • 34,080
  • 14
  • 96
  • 122
Jordan Baron
  • 3,172
  • 3
  • 13
  • 24
  • 1
    strings are immutable, you'd need to create a new string. It would be of the form `slice_before_index + char + slice_after_index`. – Paul Rooney Jan 19 '17 at 22:34
  • 5
    strings in python are immutable... this means you must construct a new string – Joran Beasley Jan 19 '17 at 22:35
  • 3
    Does this answer your question? [Changing one character in a string in Python](https://stackoverflow.com/questions/1228299/changing-one-character-in-a-string-in-python) – Georgy Apr 18 '20 at 15:05
  • For time comparison, check out this answer: https://stackoverflow.com/questions/1228299/changing-one-character-in-a-string/22149018#22149018 – MERose Dec 11 '21 at 10:56

5 Answers5

103

As strings are immutable in Python, just create a new string which includes the value at the desired index.

Assuming you have a string s, perhaps s = "mystring"

You can quickly (and obviously) replace a portion at a desired index by placing it between "slices" of the original.

s = s[:index] + newstring + s[index + 1:]

You can find the middle by dividing your string length by 2 len(s)/2

If you're getting mystery inputs, you should take care to handle indices outside the expected range

def replacer(s, newstring, index, nofail=False):
    # raise an error if index is outside of the string
    if not nofail and index not in range(len(s)):
        raise ValueError("index outside given string")

    # if not erroring, but the index is still not in the correct range..
    if index < 0:  # add it to the beginning
        return newstring + s
    if index > len(s):  # add it to the end
        return s + newstring

    # insert the new string between "slices" of the original
    return s[:index] + newstring + s[index + 1:]

This will work as

replacer("mystring", "12", 4)
'myst12ing'
ti7
  • 12,648
  • 6
  • 30
  • 60
  • 1
    when trying your function above the *xrange* function threw an error. Is there a library we need to import? – yeOldeDataSmythe Oct 21 '19 at 14:23
  • 2
    Oh, I'll make an update `xrange` is Python 2.7's version of Python 3.x's `range` – ti7 Oct 21 '19 at 21:00
  • @jeffhale the action is meant to be obvious to one _reading the code here_, not necessarily obvious in general / as a possible implementation! – ti7 Sep 08 '21 at 20:58
  • @ti7 I think Eric Blackman explains that rationale for avoiding such language best in this Nature article: https://www.nature.com/articles/550457e "This is a friendly suggestion to colleagues across all scientific disciplines to think twice about ever again using the words 'obviously' and 'clearly' in scientific and technical writing. These words are largely unhelpful, particularly to students, who may be counterproductively discouraged if what is described is not in fact obvious or clear to them. Even the most astute readers can disagree about what is clear and obvious." ... – jeffhale Sep 09 '21 at 13:44
43

You can't replace a letter in a string. Convert the string to a list, replace the letter, and convert it back to a string.

>>> s = list("Hello world")
>>> s
['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd']
>>> s[int(len(s) / 2)] = '-'
>>> s
['H', 'e', 'l', 'l', 'o', '-', 'W', 'o', 'r', 'l', 'd']
>>> "".join(s)
'Hello-World'
Jacob Malachowski
  • 766
  • 1
  • 7
  • 18
26

Strings in Python are immutable meaning you cannot replace parts of them.

You can however create a new string that is modified. Mind that this is not semantically equivalent since other references to the old string will not be updated.

You could for instance write a function:

def replace_str_index(text,index=0,replacement=''):
    return '%s%s%s'%(text[:index],replacement,text[index+1:])

And then for instance call it with:

new_string = replace_str_index(old_string,middle)

If you do not feed a replacement, the new string will not contain the character you want to remove, you can feed it a string of arbitrary length.

For instance:

replace_str_index('hello?bye',5)

will return 'hellobye'; and:

replace_str_index('hello?bye',5,'good')

will return 'hellogoodbye'.

Willem Van Onsem
  • 397,926
  • 29
  • 362
  • 485
7
# Use slicing to extract those parts of the original string to be kept
s = s[:position] + replacement + s[position+length_of_replaced:]

# Example: replace 'sat' with 'slept'
text = "The cat sat on the mat"
text = text[:8] + "slept" + text[11:]

I/P : The cat sat on the mat

O/P : The cat slept on the mat

Shivam Bharadwaj
  • 1,594
  • 20
  • 20
-2

You can also Use below method if you have to replace string between specific index

def Replace_Substring_Between_Index(singleLine,stringToReplace='',startPos=0,endPos=1):
    try:
       singleLine = singleLine[:startPos]+stringToReplace+singleLine[endPos:]
    except Exception as e:
        exception="There is Exception at this step while calling replace_str_index method, Reason = " + str(e)
        BuiltIn.log_to_console(exception)
    return singleLine