Nick Maclaren wrote:
Martin v. Löwis wrote:
It may be a bit problematic to implement, but I think a clean specification is possible. If a and b are numbers, and a==b, then hash(a)==hash(b).
You don't even need that much complication.
If a==b, then hash(a) == hash(b)
If you have to break this, then at least one (preferably both) of (a,b) must be unhashable, so that it won't get used as a dict key.
Hashing is only ever meaningful as a shortcut to quickly show that two objects are *not* equal.
I'm not sure whether "approximately 5.0" equals 5 or not: if it does, it should hash the same as 5, if it doesn't, it may or may not hash the same (whatever is easier to implement).
For 0: hash(+0.0)==hash(-0.0)==hash(0)=hash(0L)=0
Unfortunately, that assumes that equality is transitive.
No, but the (transitively closed set of equivalent objects) must have the same hash. If
>>> myfloat(5.0) != 5.0 True
then you could just return 47 as the hash. It might not be terribly efficient, but it would work.
>>> myfloat_exact(5.0) == 5.0 == myfloat_approx(5.0) != myfloat_exact(5.0)
then at least one of (myfloat_exact, myfloat_approx) needs to be unhashable, so that it can't be used as a dictionary key.
let us say that I am implementing a special function and want to distinguish -0.0 and +0.0. Why can't I use a dictionary?
Because they are equal. They aren't identical, but they are equal.
a = float("+0.0") b = float("-0.0") print a, b
With the standard windows distribution, I get just
No, I don't have an answer. You are damned if you do, and damned if you don't. It is an insoluble problem, and CURRENTLY doesn't justify two hashing mechanisms (i.e. ANY difference and EQUALITY difference).
You want something in between "__eq__" and "is". (a.identical(b) ?) Hashing is weaker than either.
>>> hash ("JimJ") == hash (2010274390) True