Take the following code for example:
t=(1,2,3)
t+=(4,)
print(t)
The printed value is (1,2,3,4).Didn't the value of tuple t just got changed which is similar to an append/extend method for list objects?
You can concatenate tuples into a new tuple. You're replacing the value of t
entirely with a new value. You cannot modify an existing tuple. To illustrate:
t = (1, 2, 3)
u = t
t += (4,) # shorthand for t = t + (4,)
t == u # False
t is u # False
t
and u
do not refer to the same object anymore.
With mutable data structures, that would not be the case:
t = [1, 2, 3]
u = t
t.append(4)
t == u # True
t is u # True
Tuples are immutable. That is they can not be changed like lists in python. What you are doing is, just replacing old tuple with new tuple.
t += (4,)
is more or less syntactical sugar. It translates to
t = t.__iadd__((4,))
(assuming this method exists. If it doesn't, it falls back to t = t + (4,)
). Since tuples are immutable, at best __iadd__
would return a new tuple that gets bound to the old name t
. For lists in a similar setting the returned list would be the (mutated) original.
What you are doing is re-assignment of a new tuple object to the variable t
. You are not modifying the same object.
Let's start disassembling the code..
See this (Notice STORE_FAST
in second block (85
)):
import dis
def tup_concat():
t = (1, 2, 3)
t += (4,)
print(t)
84 0 LOAD_CONST 1 ((1, 2, 3))
2 STORE_FAST 0 (t)
85 4 LOAD_FAST 0 (t)
6 LOAD_CONST 2 ((4,))
8 INPLACE_ADD
10 STORE_FAST 0 (t)
86 12 LOAD_GLOBAL 0 (print)
14 LOAD_FAST 0 (t)
16 CALL_FUNCTION 1
18 POP_TOP
20 LOAD_CONST 0 (None)
22 RETURN_VALUE
However, if you truly modify an object (say list) it would look something like this:
import dis
def modify():
t = [4,6,7]
t.append(4)
dis.dis(modify)
89 0 LOAD_CONST 1 (4)
2 LOAD_CONST 2 (6)
4 LOAD_CONST 3 (7)
6 BUILD_LIST 3
8 STORE_FAST 0 (t)
90 10 LOAD_FAST 0 (t)
12 LOAD_METHOD 0 (append)
14 LOAD_CONST 1 (4)
16 CALL_METHOD 1
18 POP_TOP
20 LOAD_CONST 0 (None)
22 RETURN_VALUE
Notice: There is no STORE_FAST
in second block (90
).
Conclusion: It does not refer to the same object (variable t
before and after INPLACE_ADD
).