Why is dictionary.keys() a list and not a set?
Christoph Zwerschke
cito at online.de
Thu Nov 24 18:52:02 EST 2005
Mike Meyer wrote:
> Well, I just made a suggestion. You found the problem - you want to do
> the PR, or should I?
Please go ahead if you have the time. By the way, the doco may be also
inexact about the keys of dictionaries.
> # Untested code
> class Hash(object):
> def __new__(cls, obj):
> if hasattr(obj, '__hash__'):
> return obj
> self.__obj = obj
> return object.__new__()
> def __getattr__(self, name):
> return getattr(self.__obj, name)
> def __setattr(self, name, value):
> setattr(self.__obj, name, value)
> def __hash__(self):
> return id(self.__obj)
This will not work since even lists seem to have a __hash__ attribute.
Also, you will get an infinite recursion when trying to access
self.__obj. But principally, it should work. Ad hoc solution:
class HashProxy:
def __init__(self, obj):
self.__obj = obj
def __getattr__(self, name):
return getattr(self.__obj, name)
def __setattr(self, name, value):
setattr(self.__obj, name, value)
def __hash__(self):
return id(self.__obj)
def Hash(obj):
try:
hash(obj)
except TypeError:
return HashProxy(obj)
else:
return obj
> If you need to turn a list of arbitrary, possibly unhashable, objects
> into a set, is there a problem with the above?
Well, first you don't get the real unhashable objects, but proxied
objects. This will lead to problems if you want to check the type in the
following - you will always get the same type. Second, as you have
already mentioned, the elements of the sets will not be guaranteed to be
different anymore (only different in terms of identity (is), but they
still may be equal (==)). This would not be what you expect from a set.
-- Christoph
More information about the Python-list
mailing list