Dictionary keys (again) (was Re: lambda)

Steven Bethard steven.bethard at gmail.com
Wed Jan 19 15:22:23 EST 2005


David Eppstein wrote:
> In article <mailman.893.1106130899.22381.python-list at python.org>,
>  Nick Coghlan <ncoghlan at iinet.net.au> wrote:
> 
> 
>>For a 'mutable key' to make sense, the following:
>>
>>lst = []
>>dct = {l: "Hi!"}
>>print dct[[]]
>>print dct[lst]
>>lst.append(1)
>>print dct[[1]]
>>print dct[lst]
>>
>>Should print:
>>Hi
>>Hi
>>Hi
>>Hi
> 
> 
> Yes, and what should the following do?
> 
> lst1 = [1]
> lst2 = [2]
> dct = {lst1: "1", lst2: "2"}
> lst2[0]=1
> lst1[0]=2
> print dct[[1]]
> print dct[[2]]

Depends on when you want the updates done.  Since my implementation only 
rehashes when the dict is accessed, neither key gets overwritten in this 
case:

py> class sillylist(list):
...     def __hash__(self):
...         return hash(tuple(self))
...
py> class sillydict(dict):
...     def _rehash(self):
...         items = self.items()
...         self.clear()
...         self.update(items)
...     def __getitem__(self, key):
...         self._rehash()
...         return super(sillydict, self).__getitem__(key)
...     def __setitem__(self, key, value):
...         self._rehash()
...         return super(sillydict, self).__setitem__(key, value)
...
py> lst1 = sillylist([1])
py> lst2 = sillylist([2])
py> dct = sillydict({lst1:"1", lst2:"2"})
py> lst2[0] = 1
py> lst1[0] = 2
py> print dct[sillylist([1])]
2
py> print dct[sillylist([2])]
1

The nastier question is, what should the following code do:

lst1 = [1]
lst2 = [2]
dct = {lst1: "1", lst2: "2"}
lst2[0]=1
print dct[[1]]
print dct[[2]]

My implementation does the following:

py> lst1 = sillylist([1])
py> lst2 = sillylist([2])
py> dct = sillydict({lst1:"1", lst2:"2"})
py> lst2[0] = 1
py> print dct[sillylist([1])]
1
py> print dct[sillylist([2])]
Traceback (most recent call last):
   File "<interactive input>", line 1, in ?
   File "<interactive input>", line 8, in __getitem__
KeyError: [2]

which is even sillier when you compare to what happens with the original 
code you posted. ;)

Steve



More information about the Python-list mailing list