list in a tuple

montyphyton at gmail.com montyphyton at gmail.com
Mon Dec 24 11:13:01 EST 2007


Like I said, it is clear *why* this happens, what I
am concerned is if this what we *want* to happen, i.e.,
if the current situation is satisfying. Your mytuple class
would be something that resembles a solution, my question
is what the people on this group think about it.

On Dec 24, 5:08 pm, Arnaud Delobelle <arno... at googlemail.com> wrote:
> On Dec 24, 3:22 pm, montyphy... at gmail.com wrote:
>
>
>
> > Recently, I got into a debate on programming.reddit.com about
> > what should happen in the following case:
>
> > >>> a = ([1], 2)
> > >>> a[0] += [3]
>
> > Currently, Python raises an error *and* changes the first element of
> > the tuple. Now, this seems like something one would want to
> > change - why raise an error *and* execute the thing it
> > was complaining about? The discussion seems to have no end, and
> > that is why I'm posting here. I would like to know what is the opinion
> > of the people on this group... Am I really mistaking for thinking that
> > this is strange and unwanted behavior? Btw I understand *why* is this
> > happening, I just think it should change...
> > And here is the post that started this discussion:http://filoxus.blogspot.com/2007/12/python-3000-how-mutable-is-immuta...
>
> > Thanks for your replies
>
> For the sake of clarity, say you have typed:
>
> >>> L = [1]
> >>> a = (L, 2)
> >>> a[0] += [3]
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> TypeError: 'tuple' object does not support item assignment>>> a
>
> ([1, 3], 2)
>
> I think that this is what happens when a[0] += [3] is executed:
>
> 1. list.__iadd__(L, [3]) is called, modifying L in place and returning
> L.
> 2. tuple.__setitem__(a, L) is tried, raising the TypeError.
>
> Notice that this problem doesn't arise when replacing lists with
> tuples:
>
> >>> a = ( (1,), 2)
> >>> a[0] += (3, )
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
> TypeError: 'tuple' object does not support item assignment>>> a
>
> ((1,), 2)
>
> This is because tuple object don't have an __iadd__ method so a new
> object tuple.__add__((1,),(3,)) is created and returned.
>
> AFAICS, the only way to avoid the error message would be to check if
> the new object is the same as the old one before raising the
> TypeError:
>
> class mytuple(tuple):
>     "It's ok to do t[i] = obj as long as t[i] was already obj"
>     def __setitem__(self, i, val):
>         if self[i] is not val:
>             raise TypeError("'mytuple' object is immutable")
>
> So:
>
> >>> a = mytuple(([1], 2))
> >>> a[0] += [3] # This now works
> >>> a[1] += 4   # This won't work as ints are immutable
>
> Traceback (most recent call last):
>   File "<stdin>", line 1, in <module>
>   File "tuple.py", line 4, in __setitem__
>     raise TypeError("'mytuple' object is immutable")
> TypeError: 'mytuple' object is immutable>>> a
>
> ([1, 3], 2)
>
> It wouldn't slow anything down I suppose, just make some currently
> failing code succeed.
>
> --
> Arnaud




More information about the Python-list mailing list