152

I tried this code to do simple string replacement:

X = "hello world"
X.replace("hello", "goodbye")

Why doesn't X change, from "hello world" to "goodbye world"?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Katherina
  • 2,153
  • 7
  • 26
  • 34

2 Answers2

256

This is because strings are immutable in Python.

Which means that X.replace("hello","goodbye") returns a copy of X with replacements made. Because of that you need replace this line:

X.replace("hello", "goodbye")

with this line:

X = X.replace("hello", "goodbye")

More broadly, this is true for all Python string methods that change a string's content "in-place", e.g. replace,strip,translate,lower/upper,join,...

You must assign their output to something if you want to use it and not throw it away, e.g.

X  = X.strip(' \t')
X2 = X.translate(...)
Y  = X.lower()
Z  = X.upper()
A  = X.join(':')
B  = X.capitalize()
C  = X.casefold()

and so on.

cs95
  • 379,657
  • 97
  • 704
  • 746
Tadeck
  • 132,510
  • 28
  • 152
  • 198
  • 1
    Pedantic point: strings can be mutated for `x += 'a'` special case, e.g. https://stackoverflow.com/a/40996908/6260170 – Chris_Rands Oct 08 '18 at 15:24
  • @Chris_Rands: Looks like you are right, but from outside it does not have a real mutability effect - some implementations check if this is really used, and if not (so mutability would not be observed), it would actually mutate. Is that true? – Tadeck Oct 09 '18 at 16:35
  • @Tadeck Well I think it is *real* but it's merely a CPython optimisation and not directly relevant here (that's why I said I was being pedantic) – Chris_Rands Oct 11 '18 at 20:29
0

All string functions as lower, upper, strip are returning a string without modifying the original. If you try to modify a string, as you might think well it is an iterable, it will fail.

x = 'hello'
x[0] = 'i' #'str' object does not support item assignment

There is a good reading about the importance of strings being immutable: Why are Python strings immutable? Best practices for using them

user1767754
  • 23,311
  • 18
  • 141
  • 164