They are not mutable. You can't modify the parts of a string by index. and most string functions return a new string from an existing string, so a new object must be created if you want to store the newly returned string. The original string is either unaffected, or is lost if the variable that pointed to it is changed to point to something else (like the new string object).
BUT, what about appending a string literal to an existing string object?
like:
a = 'great'
a+= ' day'
print(a)
now in this case below, I am returning a new string and creating a new object, the old string will be picked up by garbage collector
s = 'Hello World'
s = s.replace('l','i')
print(s)
a = 'banana'
x = ''
for i in range(len(a)):
if i == 4:
x+='t'
else:
x+=a[i] #not mutating a, since i clearly made a new object
#but then is this concatenation not considered mutation,
#or is x also being "recreated"?
print(x)
a = a + x #appending something to original object, or am i creating a new one?
print(a)
What else you can do (this is definitely not mutation):
a = 'banana'
print(a)
for i in a:
if i.isupper():
print(i.lower(), end='')
print(i,end = '')
else:
print(i.upper(), end='')
print(i,end = '')
a = a.upper()
print('\n'+a)
for i in a:
if i.isupper():
print(i.lower(), end='')
print(i,end = '')
else:
print(i.upper(), end='')
print(i,end = '')
a = a.lower()
print('\n'+a)
ls = []
for j in range(len(a)):
if a[j].isupper():
ls.append(a[j].lower())
else:
ls.append(a[j].upper())
print(ls)
s = ''
a = s.join(ls)
print(a)
Output:
banana
BbAaNnAaNnAa
BANANA
bBaAnNaAnNaA
banana
['B', 'A', 'N', 'A', 'N', 'A']
BANANA
iandawill be unchanged.