objects as mutable dictionary keys
Steven Bethard
steven.bethard at gmail.com
Mon Dec 27 17:12:52 EST 2004
Peter Maas wrote:
> This strikes me because if one can do this with instances of user
> defined classes why not with lists? Trying to use lists as dict
> keys yields "TypeError: list objects are unhashable". So why are
> list objects unhashable and user defined objects hashable? For
> user defined objects hash(x1) = id(x1), why not do the same
> with lists?
>
> I think it's because of the existence of list literals. If you
> would use id() as a hash function for lists how should d[[1,2,3]]
> be stored? For instances of user defined classes there is no
> literal and accordingly no problem to use id() as a hash function
> and instances as dictionary keys.
>
> Is that correct?
Well, there's no problem getting an id of a list without a name if
that's what you mean:
py> lst = [[1,2,3]]
py> id(lst[0])
12456424
If lists were hashable, new programmers to Python would almost certainly
make mistakes like:
py> d = {[1, 2, 3]: 'abc'}
The coder here almost certainly *doesn't* want that list to be compared
by id. The only way to get a binding for that list would be using the
dict's keys or __iter__ methods.
The coder here almost certainly wants to compare by value so that the
following code works:
py> d[[1, 2, 3]]
Of course, this is what tuples are for -- Python even supports special
syntax for using them this way:
py> d[1, 2, 3]
So my suspicion is that lists are not hashable because it prevents what
would be a very easy mistake to make. Yes, it means you can't use your
lists as keys to a dict, but how often do you want to do that anyway? I
don't think I've ever wanted to do that. If I ever do, I'll probably
just do something like:
py> lst1, lst2 = [1, 2, 3], 'a b c'.split()
py> d = {id(lst1):100, id(lst2):200}
py> d[id(lst1)]
100
py> d[id(lst2)]
200
Certainly I don't mind having to be explicit for an unusual case if it
saves me a little trouble for the more common cases.
Steve
More information about the Python-list
mailing list