I have a number of objects which I need to link to an integer number. These objects are ArcGIS Point objects (exactly what they are isn't relevant), which store an X and a Y value for a point, as floating point numbers.
I need to record that, 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
I then need to be able to look up the resulting value by the X and Y values. I've tried using the Point objects as the dictionary's key, but this doesn't work as when I recreate the point object from the X and Y values it doesn't look it up properly anymore (presumably because the object ID has changed).
How should I go about linking these point values to the integers. Is there another way that I can use a dictionary?
Add a hash method to your Point class:
...
def __hash__(self):
return hash(self.x) ^ hash(self.y)
...
In other words, the hash of a point is a munging of the hash of the x and y coordinates.
EDIT: a better hash function (based on comments here) is:
...
def __hash__(self):
return hash((self.x, self.y))
...
Because Python hashes tuples in a way that hash((p,q))
does not equal hash((q,p))
, this will avoid hash collisions for points symmetric about the diagonal.
Then, you can use your Point object as keys for dictionaries, put them in sets, etc.
Python dictionary keys need to be immutable types.
You could use a tuple like (2.765, 3.982)
. As long as a tuple contains only immutable types, it can be used as a dictionary key.
Here's my test in the console:
>>> my_dict[(12.3151, 1.2541)] = "test"
>>> my_dict[(12.3151, 1.2541)]
'test'
You could come up with a simple string convention like "2.765, 3.982"
to turn a point into an index, but that would be a waste of processing. Also, a word of caution: If for some reason you choose to do this, you must use repr
instead of str
(here's a Stack Overflow post on that topic).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With