4

When I try to modify string using += operator, and use id() method to check object's identity, string seems to be mutable. Did someone face with such a weird python behaviour?

a = '123'

print id(a)
# 89806008

a += '1'

print id(a)
# 89245728

a += '1'

print id(a)
# 89245728

print a

# '12311'

Using a = a + '1' doesnt have the same effect, and change the string id.

smci
  • 32,567
  • 20
  • 113
  • 146
bbrutall
  • 135
  • 1
  • 7
  • 3
    @Tai That question is about general rebinding of a string variable. This here is about the new object having the same memory address, indicating it is the same object. – user2390182 Jan 09 '18 at 17:02
  • @schwobaseggl Got you. – Tai Jan 09 '18 at 17:04
  • Maybe https://stackoverflow.com/questions/24245324/about-the-changing-id-of-an-immutable-string has explanation for this question? – Roman Susi Jan 09 '18 at 17:04
  • 2
    Maybe the interpreter detects that "1231" is no longer used and places "12311" at the same memory location – rrobby86 Jan 09 '18 at 17:05

1 Answers1

9

If you were correct about this string being mutable, then adding

b = a

before your second a += '1' should not have any effect on your output. But it does.

The reason is that because the string a had before the "increment" is no longer used anywhere, the id can be re-used. But by assigning that string to b, it now is used somewhere, and the new string for a can't re-use that id.

Scott Hunter
  • 48,888
  • 12
  • 60
  • 101
  • 1
    To be clear, this is a CPython specific optimization (it only works reliably in a reference-counted interpreter). You're not supposed to rely on it, per [PEP8's programming recommendations](https://www.python.org/dev/peps/pep-0008/#programming-recommendations): "For example, do not rely on CPython's efficient implementation of in-place string concatenation for statements in the form `a += b` or `a = a + b`. This optimization is fragile even in CPython (it only works for some types) and isn't present at all in implementations that don't use refcounting." – ShadowRanger Nov 27 '21 at 17:09