This is an alteration of the original string or not?
Not.
Let’s follow step by step (in a simplified way) what happens:
s = "banana"
Here we create an object of the string type (to be more precise, an instance of the class str
), whose content is the text "banana", and we assign in the variable s
. I mean, we have something like this:
Then on this line:
s = s.replace("b", "z")
Here are two things happening: first replace
returns another string (in the case, "zanana"), and then the result is assigned to the variable s
. So now it’s like this:
That is, the variable s
now point to the string "zanana". But the string "banana" is still there, unchanged (it just doesn’t have anyone pointing to it anymore, but note that it itself hasn’t been modified).
One way to see that the variable has changed (which it points to another object) is to print the id
of the same. According to documentation, in Cpython (which is probably the implementation you are using) the address of the object in memory is returned. So we can do this test:
s = "banana"
# imprime a string e o id
print(s, id(s)) # banana 19192864
s = s.replace("b", "z")
print(s, id(s)) # zanana 24317376
The exact numbers will change each time you run and will not be the same as the ones I put up. But the important thing is that the id
before and after the replace
will not be the same, because after the replace
the variable s
starts pointing to the other string that was generated, and no longer to the original.
This holds true for all methods that "modify" the string (such as upper
, lower
, etc): actually they return another string with the modified value. So much so that you can do so:
s = "banana"
# atribuir o resultado de replace para outra variável, em vez de "s"
outra = s.replace("b", "z")
print(s) # banana
print(outra) # zanana
If a string was changeable, the method replace
would change the very value of s
, but see above that was not the case. s
remained "banana", and the variable outra
, which receives the return of replace
is pointing to the new string. The detail is that this variable could be itself s
(as in your code), but this does not mean that the string has changed, but rather that the variable has started pointing to another string. Variable is one thing, and object is another.
If a string was changeable, the code below would not give error:
s = "banana"
# mudar o primeiro caractere da string (**dá erro!**)
s[0] = 'z' # TypeError: 'str' object does not support item assignment
For comparison purposes only, lists in Python are mutable, which means you can modify them without having to create another list or assign the other variable:
lista = [3, 20, 1]
print(id(lista))
# adiciona um elemento
lista.append(10)
# remove o primeiro
lista.pop(0)
# ordena
lista.sort()
print(lista) # [1, 10, 20]
print(id(lista)) # será o mesmo impresso no início
I printed out the id
from the list before and after the operations, and see that it will be the same, as it remains the same list: only its elements are changed.
Notice I don’t need to do something like lista = lista.sort()
, for sort
already sorts the list itself (instead of returning another ordered list). Same does not happen with strings, so just call replace
is not enough: you need to take the returned value because the original string is not modified. That’s what we mean by "strings are immutable".
Behold
id(s)
before after thereplace
(In Cpython theid
returns the memory address of your object - if you change, it is because you have created a new object).– Woss
Spoiler: if string was changeable, you wouldn’t need to reassign
s
ins = s.replace
, just executes.replace
that would internally change the characters, which is not what happens in practice. Lists, for example, are mutable and you can do theappend
without having to do something likelista = lista.append(...)
– Woss
s
is a variable and not a objectstring
. With the right concepts it’s easy to understand.– Maniero
@Maniero disagree, the motto of the python language is that everything is an object. Maybe what you said is true for some languages but not for Python. When you interact with the object
s
is making a call to the methodreplace
of class str.– Danizavtz
I’ve seen some people say that, but I haven’t seen a canonical document with that. Already blog of influential people in the community saying this and the rest repeating as parrot, which does not mean that is correct. I have not yet read the answer given in full because I need to leave, but the beginning seems promising, not least because hkotsubo usually responds properly and does not buy these myths that people spread around. Be alert for those who want to learn right. Any language that wants to repel a concept of computing does not deserve credit. I’m not saying that language does that.
– Maniero
Maniero, the variable s references a string object. So much so that we can use methods accessing the variable, as in s.upper(). So I didn’t understand the differentiation of variable and object in this case.
– Carlos Sanches
Carlos, initially the variable
s
points to an object (the string "banana"). After thes = s.replace(...)
, the variable points to another object (the string "zanana"). That is, the variable only points to an object, but it is not the object: see in my answer that after thereplace
the variables
points to "zanana", but the string "banana" continues to exist - that is, we have a variable (s
) and two objects (the strings "banana" and "zanana"). The variable, at the end, is just a name given to reference a value (read the links that Maniero indicated and that I also put in the answer)– hkotsubo
The fact that you can call a method of an object through the variable does not mean that the variable is the object. What happens is that the method is called in the object to which the variable points, but it is still separate things. For example,
x = 'abc'
, the variablex
points to the string "abc". Then I dox = 'z'
. The variablex
changed (now points to "z"), but the string "abc" (the object for whichx
pointed before) remains unchanged. If the variable was the object itself (ifx
was the string "abc", instead of pointing to it), when doingx = 'z'
the string "abc" would also be modified– hkotsubo