Pradeep
Pradeep

Reputation: 1107

In Python a tuple is immutable object but allows mutation of a contained list?

In Python:

>>> tup = (1,"a",[1,2,3])
>>> tup
(1, 'a', [1, 2, 3])
>>> tup[2][1] = "a"
>>> tup
(1, 'a', [1, 'a', 3])

From the above I could modify the list contents which is part of the tuple. Since tuple is immutable how is this possible? Did I understood the immutable part in a wrong way?

Upvotes: 2

Views: 2443

Answers (3)

bakkal
bakkal

Reputation: 55448

The tuple container is immutable, but the elements inside it may or may not be immutable.

The tuple in your example is indeed immutable, but it contains a reference to a mutable list.

So in the end I am able to modify the tuple contents?

No, you can't make the tuple point to a different list, but you can change what's inside the list.

When you do tup[2][1]="a", you didn't mutate the tuple, you mutated the list. The tuple still has the same reference to the list as it did before.

Snippet to see that the references haven't changed:

We can use id(), which returns the identity of the object (which in CPython returns the address of the object in memory)

>>> tup = (1,"a",[1,2,3])
>>> tup
(1, 'a', [1, 2, 3])
>>> [id(x) for x in tup]
[36090200, 140119363921520, 140119362889416]
>>> tup[2][1] = 'a'
>>> tup
(1, 'a', [1, 'a', 3])
>>> [id(x) for x in tup]
[36090200, 140119363921520, 140119362889416]

Upvotes: 2

Mike Graham
Mike Graham

Reputation: 76683

A tuple is immutable--it will always contain the same objects. If those objects are mutable, they might themselves be mutated, but the tuple will still contain that object.

Upvotes: 0

DainDwarf
DainDwarf

Reputation: 1669

You did understand the immutable part the wrong way. The tuple is indeed immutable, as you cannot change its list:

In [3]: tup[2] = []
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-02255d491606> in <module>()
----> 1 tup[2] = []

TypeError: 'tuple' object does not support item assignment

The reference to the list is immutable in that tuple. However, the list itself is mutable, and hence can be modified, as you already know.

In other words, your tuple, which is immutable, contains three elements:

  • Integer 1
  • string "a"
  • A reference to a list.

You can imagine it as the adress of the list, if you know C. If you don't know anything about memory, you can see it as "the tuple knows where to find the list". But it doesn't contain the list itself.

Upvotes: 7

Related Questions