Are tuple really immutable?

Chris chris.monnet at gmail.com
Mon Dec 27 04:03:09 CET 2004


Hi

Consider the following tuples:
>>> t = ([1],[2])
>>> u = (1,2)
>>> v = ('1','2')
>>> t
([1], [2])
>>> u
(1, 2)
>>> v
('1', '2')
>>> t.__hash__()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: list objects are unhashable
>>> u.__hash__()
219750523
>>> v.__hash__()
-1786881095
>>> d = dict()
>>> d[t] = 't'
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: list objects are unhashable
>>> d[u] = 'u'
>>> d[v] = 'v'
>>> d
{('1', '2'): 'v', (1, 2): 'u'}

t, u and v are all tuples. t and v elements are sequences.
Yet, t cannot be a dictionnary key because its elements are mutable.

1) Given a tuple, how can I know if it can be a dictionnary key or not?

Of course I could call __hash__ and catch for a TypeError exception,
but I'm  looking for a better way to do it.

2) Would it be possible to have a "ismutable" function or method? Like:
>>> t.ismutable()
True, well maybe not...
>>> u.ismutable()
False
>>> u.ismutable()
False

3) In this example, is t considered mutable or not?
"Tuple are immutable" says the doc, but:
>>> t[0].append(0)
>>> t
([1, 0], [2])

The tuple is immutable but its elements can be mutable: I tend to think
that it means that the tuple is mutable. Indeed, it changed!

4) Even more confusing: I had the following strange result:
(with both Python 2.3.3 and 2.4)
>>> t[0]+=[1]
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment
>>> t
([1, 0, 1], [2])
There was an exception, but the list was still changed!?

Chris




More information about the Python-list mailing list