It's worth noting that tuples aren't actually immutable in Python. Tuples have immutable length, but the values in those slots can be changed at runtime.
>>> (1,2,3)[2]=5
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
I wish they could. (Maybe Python 3 is different?)Can (1, 2, [3]) be used in a hash table, and what if the [3] is mutated to [3, 4]?
>>> x = (1, 2, [3])
>>> x
(1, 2, [3])
>>> x[2].append(4)
>>> x
(1, 2, [3, 4])What you did was modify the underlying list, the tuple itself is immutable.
import ctypes
def tuple_setitem(t, index, item):
obj = ctypes.py_object(t)
item = ctypes.py_object(item)
ref_count = ctypes.c_long.from_address(id(t))
original_count = ref_count.value
if original_count != 1:
ref_count.value = 1
ctypes.pythonapi.Py_IncRef(item)
ctypes.pythonapi.PyTuple_SetItem(obj, ctypes.c_ssize_t(index), item)
ref_count.value = original_count
>>> x = (1, 2, 3,)
>>> tuple_setitem(x, 1, "foo")
>>> x
(1, "foo", 3)
Disclaimer: for entertainment purposes only, do not try this at home!If it has mutable items in it, yes. But in that case, the tuple can't be used as a dictionary key; Python checks, not just that the tuple itself is immutable, but that every object in it is immutable.