I trying to understand how the immutability works in python. Since string are immutable in python, I was expecting the id to change every time I perform a string operation but it doesn't work as expected. example: The last operation on t doesn't change its id. Any ideas why?
-
Related: [About the changing id of a Python immutable string](http://stackoverflow.com/questions/24245324/about-the-changing-id-of-a-python-immutable-string) – fredtantini Feb 21 '17 at 16:18
-
1I really hate how this optimization violates the Python language semantics. According to the language semantics, the values of `t` before and after the `+=` should be different objects with (barely) overlapping lifetimes, so it should be impossible for them to share an `id`. – user2357112 Feb 21 '17 at 16:49
2 Answers
I had a row of apples in different cells [memory containing variables (I will not go to the bit level)]
, of which some were empty [cells containing garbage / empty value]
.
I took one out. It was in cell 3 [logical address = 3]
.
I painted it blue (after I cloned it using future tech, for immutability demonstration) [committed an operation on it, same could go for addition for integers]
.
I looked where to put it, and although cell 4 was free, cell 3 was also (because the "original" apple is not here anymore)! So I put it back in cell 3 [and although we get a "new" apple, it has the same address]
.
Same goes for your t
(note that id
is the memory address of the variable in CPython), but since we are talking about "chains of apples" here (strings are made of a characters sequence, we have to consider the amount of space we have to continue the sequence, so if I had my memory looking like (_
stands for arbitrary garbage data, '^' for space)
H e l l o _ _ _ _ _ B O O M
^ string pointer points here
and I wanted to change the string to "Hello you"
, I might consider using the free space:
H e l l o ^ y o u _ B O O M
^ string pointer points here
But if I want to change the string to "Hello world!"
, I would have to look for free space in the length of "Hello world!"
somewhere else (we might have it right after "BOOM"
, which is probable in a garbage collected environment, look at how your IDs differs):
H e l l o ^ y o u _ B O O M _ H e l l o ^ w o r l d ! _ G A R B A G E
^ string pointer points here

- 15,579
- 6
- 25
- 46
-
@B.M. The issue there is the similarity to interning.What I wrote is basically like Martijn's comment over there - `"Python is free to reuse memory slots."` – Uriel Feb 21 '17 at 16:27
-
@B.M. I can't understand what you mean by "It does'nt [sic!] work like that." What this answer is describing is that Python is reusing a memory address for a new string because the previous string got garbage-collected. I looked at the link and I can't see how it would provide an alternative explanation for the phenomenon described in the question. – Rörd Feb 21 '17 at 16:38
-
Sorry, it was too direct. I post something to explain what I understood. I think in this example, the blue apple is not put in cell 3, you just let the green one here and add blue paint at the end of cell3. – B. M. Feb 21 '17 at 16:46
-
1This is a terrible explanation. It's hard to interpret what the row, the apples, or the cells are supposed to be, and it doesn't explain why we can "paint" the immutable apple or why cell 3 is free. – user2357112 Feb 21 '17 at 16:51
-
@user2357112 I added the metaphors as blue comments. Though I believe it was pretty clear. – Uriel Feb 21 '17 at 17:01
Ids of objects can be reused, as long as the original object is no longer present. This is not specific to strings, but to all Python types. For the simplest example, you can examine the id of a simple object
:
>>> print id(object())
140437485756544
>>> print id(object())
140437485756544
However, if we retain a reference to the previous object, the id will not be reused:
>>> a = object()
>>> id(a)
140437485756544
>>> b = object()
>>> id(b)
140437485756560
You can reproduce the same behavior in your tests with strings by appending the intermediate results (values in t
) to a list.

- 141,790
- 18
- 296
- 355
-
Why in the first two test cases of appending "Test" to t did the id change? Is this "random" or does python have a systematic way of allocating memory for strings in this case? – Preston Martin Feb 21 '17 at 16:41
-
1@PrestonM The id is not guaranteed to be reused - something else may have taken that memory location (which is how CPython implements `id`) the first time. What is guaranteed is that the ID of a live object doesn't change, and that no two distinct (and live) objects will share the same ID. – user4815162342 Feb 21 '17 at 16:47