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