Why are tuples immutable?

Steven Bethard steven.bethard at gmail.com
Wed Dec 22 13:03:33 EST 2004


Antoon Pardon wrote:
> Well the only suggestion I would make now is that it would be nice to
> have a second dict type that would make a copy of a key and insert
> that copy in the dictionary.

(At least) two options here, depending on what you really need.

(1) Use current dicts.  They will still give you a key error if you 
mutate a list that is hashed by value:

py> class hashablelist(list):
...     def __hash__(self):
...         return hash(tuple(self))
...
py> hlist = hashablelist([0])
py> hlist
[0]
py> d = {hlist:1}
py> d
{[0]: 1}
py> d[hlist]
1
py> hlist[0] = 1
py> d[hlist]
Traceback (most recent call last):
   File "<interactive input>", line 1, in ?
KeyError: [1]

Since you've said yourself that you don't think people should be 
mutating keys while they're in a dict, this behavior should serve most 
purposes.  If you do care what the errors are when someone does mutate a 
key, using a dict means that you could potentially "lose" values after 
mutating a key.  Continuing the example above:

py> d
{[1]: 1}
py> d[hashablelist([0])]
Traceback (most recent call last):
   File "<interactive input>", line 1, in ?
KeyError: [0]
py> d[hashablelist([1])]
Traceback (most recent call last):
   File "<interactive input>", line 1, in ?
KeyError: [1]


(2) If you want something that meets your specs better, sit down and 
write the 10 lines of code: =)

py> class copydict(object, UserDict.DictMixin):
...     def __init__(self, *args, **kwds):
...         self._dict = {}
...         self.update(*args, **kwds)
...     def __getitem__(self, key):
...         return self._dict[key]
...     def __setitem__(self, key, value):
...         self._dict[copy.deepcopy(key)] = value
...     def __iter__(self):
...         return iter(self._dict)
...
py> hlist = hashablelist([0])
py> cdict = copydict({hlist:1})
py> cdict[hlist]
1
py> hlist[0] = 1
py> cdict[hlist]
Traceback (most recent call last):
   File "<interactive input>", line 1, in ?
   File "<interactive input>", line 6, in __getitem__
KeyError: [1]
py> cdict[hashablelist([0])]
1
py> list(cdict)
[[0]]

I personally, have zero need for such a class, but if you think that 
it's useful, and you think a lot of other people might use it, put 
together a PEP and ask for it to be added to, say, collections, in the 
standard library.

Steve



More information about the Python-list mailing list