Before I get going, I know strings aren't mutable, which is why I am perplexed. I was writing myself a simple example, to prove that strings aren't mutable, and I can't explain my results.
alphabet = "bcdefghijklmnopqrstuvwxy"
print(hex(id(alphabet))) #memory address 'abc'
print(alphabet)
print('\nalphabet = "a" + alphabet:')
alphabet = "a" + alphabet
print(hex(id(alphabet))) #memory address 'xyz'
print(alphabet)
print('\nalphabet += z:')
alphabet += "z"
print(hex(id(alphabet))) #memory address 'xyz'
print(alphabet)
I would have expected the 2nd and third strings to have different memory address, but they do not. It would indicate that the string was not copied, but changed.
Can anyone help explain this discrepancy?
Thanks!
Quote:Can anyone help explain this discrepancy?
It's not a descrepency, this is what I suspect happens.
line 6 assigns a memory location for alphabet, then
line 11, with the += is the same as:
alphabet = alphabet + "z"
so, the memory location is reused by the compiler for the new string.
that space is reused in step 11, it could just as well have been another memory address, but is optimized.
Even if it did use a different memory location, it would still be valid as the first in line 6 would not.
If you want to go there, you can always look at the source code:
https://github.com/python, not at all a trivial task!
That may be an efficiency with += for strings. Since you are adding on to the end of the string, and not creating a new variable name, Python may just add on to the underlying sequence in memory without moving anything around. Mutability/immutability is less of a memory thing than how multiple references to things are handled.
String immutability refers to the object,not the variable which can have other names tag to it.
Python has names,Other languages have variables
>>> alphabet = "bcdefghijklmnopqrstuvwxy"
>>> alphabet[-1] = 'z'
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: 'str' object does not support item assignment
Strings don't support item assignment because they are immutable.
Using list which is mutable,then no error.
>>> alphabet = list("bcdefghijklmnopqrstuvwxy")
>>> alphabet[-1] = 'z'
>>> ''.join(alphabet)
'bcdefghijklmnopqrstuvwxz'
What does id() return:
Help on built-in function id in module builtins:
id(obj, /)
Return the identity of an object.
This is guaranteed to be unique among simultaneously existing objects.
(CPython uses the object's memory address.)
(END)
It returns unique identity (and in CPython its memory address). Important is that it's unique 'among simultaneously existing objects'.
This is interpreter optimisation thingy rather than mutable string:
>>> a = 'abc'
>>> id(a)
4408678192
>>> a += 'abc'
>>> id(a)
4706923496
>>> a = a + 'e'
>>> id(a)
4706923496
>>> a = a + 'fg'
>>> id(a)
4713804080
Running your code in Jupyter Lab or in Azure Notebook returns three different identities right away:
Output:
0x7f8890b235d0
bcdefghijklmnopqrstuvwxy
alphabet = "a" + alphabet:
0x7f8890b233f0
abcdefghijklmnopqrstuvwxy
alphabet += z:
0x7f8890b238a0
abcdefghijklmnopqrstuvwxyz
Thanks everyone! I thought I had a good grasp on the topic, thanks for schooling me!