set using alternative hash function?
Diez B. Roggisch
deets at nospam.web.de
Thu Oct 15 08:22:19 EDT 2009
Chris Rebert wrote:
> On Thu, Oct 15, 2009 at 4:24 AM, Austin Bingham
> <austin.bingham at gmail.com> wrote:
>> If I understand things correctly, the set class uses hash()
>> universally to calculate hash values for its elements. Is there a
>> standard way to have set use a different function? Say I've got a
>> collection of objects with names. I'd like to create a set of these
>> objects where the hashing is done on these names. Using the __hash__
>> function seems inelegant because it means I have to settle on one type
>> of hashing for these objects all of the time, i.e. I can't create a
>> set of them based on a different uniqueness criteria later. I'd like
>> to create a set instance that uses, say, 'hash(x.name)' rather than
>> 'hash(x)'.
>>
>> Is this possible? Am I just thinking about this problem the wrong way?
>> Admittedly, I'm coming at this from a C++/STL perspective, so perhaps
>> I'm just missing the obvious. Thanks for any help on this.
>
> You could use wrapper objects that define an appropriate __hash__():
>
> #*completely untested*
> class HashWrapper(object):
> def __init__(self, obj, criteria):
> self._wrapee = obj
> self._criteria = criteria
>
> #override __hash__() / hash()
> def __hash__(self):
> return hash(self._criteria(self._wrapee))
>
> #proxying code
> def __getattr__(self, name):
> return getattr(self._wrapee, name)
>
> def __setattr__(self, name, val):
> setattr(self._wrapee, name, val)
This doesn't work for conflicting elements, as the __eq__-method isn't
overriden.
Diez
More information about the Python-list
mailing list