Python dict pointer over an object or two floats

I have a number of objects that I need to associate with an integer. These objects are ArcGIS Point objects (exactly what they do not matter) that store the X and Y values ​​for the point as floating point numbers.

I need to write this, for example:

Point(X = 2.765, Y = 3.982) -> 2 Point(X = 33.9, Y = 98.45) -> 7 Point(X = 1.23, Y = 2.43) -> 9 Point(X = 8.342, Y = 6.754) -> 5 

Then I need to be able to search for the resulting value by the values ​​of X and Y. I tried to use Point objects as a dictionary key, but this does not work, because when I recreate a point object from the values ​​of X and Y, it no longer looks right (presumably because the identifier of the object has changed).

How do I relate these point values ​​to integers. Is there any other way to use a dictionary?

+6
python dictionary floating-point hash
source share
5 answers

Add the hash method to your Point class:

 ... def __hash__(self): return hash(self.x) ^ hash(self.y) ... 

In other words, a point hash is a clogging hash of the x and y coordinates.

EDIT: best hash function (based on comments here):

 ... def __hash__(self): return hash((self.x, self.y)) ... 

Since Python uses hashing in such a way that hash((p,q)) not equal to hash((q,p)) , this will avoid hash collisions for points symmetrical about the diagonal.

Then you can use the Point object as keys for dictionaries, put them in a set, etc.

+10
source share

The keys of a Python word must be immutable types.

You can use a tuple like (2.765, 3.982) . While a tuple contains only immutable types, it can be used as a dictionary key.

Here is my test in the console:

 >>> my_dict[(12.3151, 1.2541)] = "test" >>> my_dict[(12.3151, 1.2541)] 'test' 

You can come up with a simple line symbol, such as "2.765, 3.982" , to turn a point into an index, but that would be a waste of processing. Also, a caution: if for some reason you decide to do this, you should use repr instead of str ( here's the Stack post on this topic).

+4
source share
+1
source share
+1
source share

Add the __hash__() method to the point class, as Payne said. Or manually calculate the hash for each point. In any case, use something like what Python originally did:

 ... def __hash__(self): return hash( (self.x, self.y ) ) ... 
+1
source share

All Articles