hashkey/digest for a complex object

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sun Oct 10 10:28:42 EDT 2010


On Sun, 10 Oct 2010 11:06:00 +0100, Arnaud Delobelle wrote:

> Steven D'Aprano <steve at REMOVE-THIS-cybersource.com.au> writes:
> 
>> On Sat, 09 Oct 2010 21:39:51 +0100, Arnaud Delobelle wrote:
>>
>>> 1. hash() is an idempotent function, i.e. hash(hash(x)) == hash(x)
>>> hold for any hashable x (this is a simple consequence of the fact that
>>> hash(x) == x for any int x (by 'int' I mean 2.X int)).
>>
>> It's a beautiful theory, but, alas, it is not the case.
>>
>>>>> hash(-1) == -1
>> False
>>>>> hash(2**64) == 2**64
>> False
>>
>> to give only two of an infinite number of counter-examples.
> 
> I can only see one counterexample, (-1).  2**64 is of type 'long' in 2.X
> on your machine (or, to be pedantic, 2.x where x >= 2).  And, in fact,
> (-1) is the only int such that hash(x) != x.

Fair point. I was mistaken.

I had the impression that the integration between ints and longs since 
Python 2.2 was more extensive than it actually is. I made the above 
comments based on the idea that since Python 2.2, longs are a subclass of 
ints, e.g. that isinstance(2**64, int) would return True. Turns out that 
I'm wrong, in which case I agree with you that -1 is the only int counter-
example.

As an aside, this makes me glad that I have continued writing 
isinstance(x, (int, long)) in my code, even though I "knew" it was 
unnecessary. Not the first time, and probably not the last, that a "this 
can never happen" test saved the day.


-- 
Steven



More information about the Python-list mailing list