set using alternative hash function?

OKB (not okblacke) brenNOSPAMbarn at NObrenSPAMbarn.net
Fri Oct 16 03:39:11 EDT 2009


Austin Bingham wrote:

> To put it in code, I want this:
> 
>   s = set(hash_func = lambda obj: hash(obj.name), eq_func = ...)
>   ...
>   x.name = 'foo'
>   y.name = 'foo'
>   s.add(x)
>   s.add(y) # no-op because of uniqueness criteria
>   assert len(s) == 1

    	The part of this that seems ill-defined to me is the line you 
describe as a "no-op".  A set keeps uniqueness because all the elements 
really are unique in the sense of equality, so if x == y and x is in s, 
and then you do s.add(y), you cannot know or care whether it "overwrote" 
the existing element with y, or did a no-op.  The two are equivalent, 
because either way the result is an element equal to x.

    	But what you seem to want is one where adding an element that's 
equal on the "key" is guaranteed a no-op and not an overwrite.  This is 
different, because (until you pasted this code) you didn't specify what 
you wanted to happen when you inserted a new item that had an equal key 
to an existing one, but was unequal to it.

    	So, can't you just use a dict and use the setdefault method instead 
of regular attribute access?  This seems to do exactly what you want.

d = {}
x.name = 'foo'
y.name = 'foo'
d.setdefault(x.name, x)
d.setdefault(y.name, y)

    	If you really want the syntactic sugar of [], you could write a 
simple class that wraps a dict and maps MyDict[x] to 
dict.setdefault(x.name, x).

-- 
--OKB (not okblacke)
Brendan Barnwell
"Do not follow where the path may lead.  Go, instead, where there is
no path, and leave a trail."
	--author unknown



More information about the Python-list mailing list