If you disassemble the following function
def test():
t = (1, 2, [30])
t[2] += [40]
return t
You'll see that the corresponding bytecode for t[2] += [40]
looks like this:
3 18 LOAD_FAST 0 (t)
21 LOAD_CONST 2 (2)
24 DUP_TOPX 2
27 BINARY_SUBSCR
28 LOAD_CONST 4 (40)
31 BUILD_LIST 1
34 INPLACE_ADD
35 ROT_THREE
36 STORE_SUBSCR
[40]
is concatenated to the list stored in t[2]
after INPLACE_ADD
, why does Python decide to add a STORE_SUBSCR
anyway?
This is because
INPLACE_ADD
only requests that the operation be done in place if possible; if the object is immutable or has not bothered to implement__iadd__
,INPLACE_ADD
falls back on regular, not-in-place addition. If the code wasit would obviously be necessary to store the new tuple back into
t[2]
, since the operation produces a new tuple instead of mutating the old one.