On Thu, Oct 15, 2009 at 4:24 AM, Austin Bingham <austin.bing...@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) #example def name_of(obj): return obj.name def name_and_serial_num(obj): return obj.name, obj.serial_number no_same_names = set(HashWrapper(obj, name_of) for obj in some_collection) no_same_name_and_serial = set(HashWrapper(obj, name_and_serial_num) for obj in some_collection) Cheers, Chris -- http://blog.rebertia.com -- http://mail.python.org/mailman/listinfo/python-list