索引python dict由对象或两个浮点数

rob*_*ntw 6 python floating-point hash dictionary

我有许多对象需要链接到整数.这些对象是ArcGIS Point对象(确切地说它们不相关),它将点的X和Y值存储为浮点数.

我需要记录下来,例如:

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
Run Code Online (Sandbox Code Playgroud)

然后,我需要能够通过X和Y值查找结果值.我已经尝试使用Point对象作为字典的键,但这不起作用,因为当我从X和Y值重新创建点对象时它不再正常查找(可能是因为对象ID已更改) .

我该如何将这些点值链接到整数.还有其他方法可以使用字典吗?

pay*_*yne 10

向Point类添加哈希方法:

...
def __hash__(self):
    return hash(self.x) ^ hash(self.y)
...
Run Code Online (Sandbox Code Playgroud)

换句话说,点的散列是x和y坐标的散列的重叠.

编辑:更好的哈希函数(基于这里的评论)是:

...
def __hash__(self):
    return hash((self.x, self.y))
...
Run Code Online (Sandbox Code Playgroud)

因为Python以hash((p,q))不相等的方式散列元组,所以hash((q,p))这将避免对于关于对角线对称的点的散列碰撞.

然后,您可以使用Point对象作为字典的键,将它们放在集合中等.


Kyl*_*ild 4

Python 字典键必须是不可变类型。

您可以使用像 那样的元组(2.765, 3.982)。只要元组仅包含不可变类型,它就可以用作字典键。

这是我在控制台中的测试:

>>> my_dict[(12.3151, 1.2541)] = "test"
>>> my_dict[(12.3151, 1.2541)]
'test'
Run Code Online (Sandbox Code Playgroud)

可以想出一个简单的字符串约定,例如"2.765, 3.982"将点转换为索引,但这会浪费处理。另外,请注意:如果由于某种原因您选择这样做,则必须使用repr而不是str这是关于该主题的 Stack Overflow 帖子)。

  • @dorkitude、@admalledd、@robintw:仅使用元组中的浮点数不会造成准确性损失:`dict_key = (point.x, point.y)`。将它们转换为字符串或十进制只是为了在哈希函数中使用会浪费 CPU 时间(如果使用“str()”而不是“repr()”,则会损失准确性)。 (2认同)