Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
A += B Assignment Riddle in Python
The += operator on a mutable object inside a tuple creates a surprising Python riddle − the operation succeeds (the list gets modified) but also raises a TypeError because tuples don't support item assignment. Both things happen simultaneously.
The Riddle
Define a tuple with a list as one of its elements, then try to extend the list using += ?
tupl = (5, 7, 9, [1, 4]) tupl[3] += [6, 8]
Traceback (most recent call last): File "", line 1, in TypeError: 'tuple' object does not support item assignment
But if you check the tuple after the error −
print(tupl)
(5, 7, 9, [1, 4, 6, 8])
The list was modified even though an error was raised.
Why Does This Happen?
The += operator on tupl[3] performs two operations internally −
-
Step 1 (INPLACE_ADD) − Calls
list.__iadd__([6, 8])on the list object attupl[3]. This succeeds because lists are mutable. The list is now[1, 4, 6, 8]. -
Step 2 (STORE_SUBSCR) − Tries to assign the result back to
tupl[3]. This fails because tuples don't support item assignment.
So the list mutation happens first, then the tuple assignment fails − giving us both a modified list and an error.
Bytecode Analysis
We can confirm this using Python's dis module to inspect the bytecode ?
import dis
def immut_function():
tupl = (5, 7, 9, [1, 4])
tupl[3] += [6, 8]
dis.dis(immut_function)
2 0 LOAD_CONST 1 (5)
3 LOAD_CONST 2 (7)
6 LOAD_CONST 3 (9)
9 LOAD_CONST 4 (1)
12 LOAD_CONST 5 (4)
15 BUILD_LIST 2
18 BUILD_TUPLE 4
21 STORE_FAST 0 (tupl)
3 24 LOAD_FAST 0 (tupl)
27 LOAD_CONST 6 (3)
30 DUP_TOPX 2
33 BINARY_SUBSCR # Get tupl[3] (the list)
34 LOAD_CONST 7 (6)
37 LOAD_CONST 8 (8)
40 BUILD_LIST 2
43 INPLACE_ADD # List mutation succeeds here
44 ROT_THREE
45 STORE_SUBSCR # Tuple assignment fails here
46 LOAD_CONST 0 (None)
49 RETURN_VALUE
At instruction 43 (INPLACE_ADD), the list is successfully extended. At instruction 45 (STORE_SUBSCR), the assignment back to the tuple raises TypeError.
The Safe Alternative
Use extend() instead of += to modify a list inside a tuple without triggering the assignment step ?
tupl = (5, 7, 9, [1, 4]) tupl[3].extend([6, 8]) # No error ? no assignment to tuple print(tupl)
(5, 7, 9, [1, 4, 6, 8])
Conclusion
The += riddle occurs because the operator performs mutation first (succeeds on the mutable list) then assignment (fails on the immutable tuple). Avoid placing mutable objects inside tuples, or use extend() instead of += to modify lists within tuples without errors.
