Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does += of a list within a Python tuple raise TypeError but modify the list anyway? [duplicate]

Tags:

python

I just came across something that was quite strange.

>>> t = ([],)
>>> t[0].append('hello')
>>> t
(['hello'],)
>>> t[0] += ['world']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> t
(['hello', 'world'],)

Why does it raise TypeError and yet change the list inside the tuple?

like image 874
satran Avatar asked May 01 '12 11:05

satran


People also ask

Can you modify a list within a tuple?

Once a tuple is created, you cannot change its values. Tuples are unchangeable, or immutable as it also is called. But there is a workaround. You can convert the tuple into a list, change the list, and convert the list back into a tuple.

Can tuples be mutated?

Tuples and lists are the same in every way except two: tuples use parentheses instead of square brackets, and the items in tuples cannot be modified (but the items in lists can be modified). We often call lists mutable (meaning they can be changed) and tuples immutable (meaning they cannot be changed).

Can you extend a list with a tuple?

To append tuple to the list, we can use the list extend() method. First, define a tuple and list and then append tuple to list using extend() method.


2 Answers

As I started mentioning in comment, += actually modifies the list in-place and then tries to assign the result to the first position in the tuple. From the data model documentation:

These methods are called to implement the augmented arithmetic assignments (+=, -=, =, /=, //=, %=, *=, <<=, >>=, &=, ^=, |=). These methods should attempt to do the operation in-place (modifying self) and return the result (which could be, but does not have to be, self).

+= is therefore equivalent to:

t[0].extend(['world']);
t[0] = t[0];

So modifying the list in-place is not problem (1. step), since lists are mutable, but assigning the result back to the tuple is not valid (2. step), and that's where the error is thrown.

like image 157
Felix Kling Avatar answered Sep 20 '22 08:09

Felix Kling


This is on http://bugs.python.org/issue11562.

like image 40
Noufal Ibrahim Avatar answered Sep 18 '22 08:09

Noufal Ibrahim