Индексный диктон по объекту или двум поплавкам - PullRequest
6 голосов
/ 21 января 2011

У меня есть несколько объектов, которые мне нужно связать с целым числом. Эти объекты являются объектами 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

Затем мне нужно найти итоговое значение по значениям X и Y. Я пытался использовать объекты Point в качестве ключа словаря, но это не работает, так как, когда я воссоздаю объект Point из значений X и Y, он больше не ищет его должным образом (предположительно, потому что идентификатор объекта изменился) .

Как мне связать эти значения точек с целыми числами. Есть ли другой способ использования словаря?

Ответы [ 5 ]

10 голосов
/ 21 января 2011

Добавьте хеш-метод к вашему классу Point:

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

Другими словами, хэш точки - это хэш координаты x и y.

РЕДАКТИРОВАТЬ: лучшая хеш-функция (на основе комментариев здесь):

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

Поскольку Python хэширует кортежи таким образом, что hash((p,q)) не равен hash((q,p)), это позволит избежать коллизий хешей для точек, симметричных относительно диагонали.

Затем вы можете использовать объект Point в качестве ключей для словарей, складывать их в наборы и т. Д.

4 голосов
/ 21 января 2011

Ключи словаря Python должны быть неизменяемыми.

Вы можете использовать кортеж как (2.765, 3.982). Пока кортеж содержит только неизменяемые типы, он может использоваться как ключ словаря.

Вот мой тест в консоли:

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

Вы могли бы придумать простое строковое соглашение, например "2.765, 3.982", чтобы превратить точку в индекс, но это было бы пустой тратой обработки. Также, предостережение: если по какой-то причине вы решите это сделать, вы должны использовать repr вместо str ( здесь пост переполнения стека на эту тему).

1 голос
/ 15 февраля 2011

Добавьте метод __hash__() к классу точек, как сказал Пейн.Или вручную вычислить хеш для каждой точки.В любом случае, используйте что-то вроде того, что Python будет делать изначально:

...
def __hash__(self):
    return hash( (self.x, self.y ) )
...
1 голос
/ 21 января 2011

Использовать именованный кортеж: http://docs.python.org/dev/library/collections.html#collections.namedtuple

1 голос
/ 21 января 2011
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...