2011-01-21 28 views
6

Tôi có một số đối tượng mà tôi cần phải liên kết đến một số nguyên. Các đối tượng này là các đối tượng ArcGIS Point (chính xác những gì chúng không liên quan), lưu trữ một giá trị X và Y cho một điểm, dưới dạng các số dấu phẩy động.Chỉ số python dict theo đối tượng hoặc hai phao

tôi cần phải ghi lại rằng, ví dụ:

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 

sau đó tôi cần để có thể tìm kiếm các giá trị kết quả bởi các giá trị X và Y. Tôi đã thử sử dụng đối tượng Point làm khóa của từ điển, nhưng điều này không hoạt động khi tôi tạo lại đối tượng điểm từ các giá trị X và Y mà nó không tìm kiếm đúng cách nữa (có lẽ vì ID đối tượng đã thay đổi) .

Tôi nên liên kết các giá trị điểm này với các số nguyên như thế nào. Có cách nào khác để tôi có thể sử dụng từ điển không?

Trả lời

4

Khóa từ điển Python cần phải là loại không thay đổi.

Bạn có thể sử dụng bộ dữ liệu như (2.765, 3.982). Miễn là tuple chỉ chứa các loại không thay đổi, nó có thể được sử dụng như một khóa từ điển.

Dưới đây là thử nghiệm của tôi trong giao diện điều khiển:

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

Bạn thể đưa ra một quy ước chuỗi đơn giản như "2.765, 3.982" để biến một điểm vào một chỉ số, nhưng đó sẽ là một sự lãng phí chế biến. Ngoài ra, một lời cảnh báo: Nếu vì lý do nào đó mà bạn chọn thực hiện việc này, bạn phải sử dụng repr thay vì str (here's một bài đăng Tràn ngăn xếp trên chủ đề đó).

+0

Cảm ơn. Điều này sẽ gây ra vấn đề với phao mặc dù, vì chúng không thể được lưu trữ chính xác. Tôi chỉ lo lắng rằng việc chuyển đổi các float thành chuỗi và sử dụng chúng để lập chỉ mục sẽ dẫn đến các vấn đề với các float không chuyển đổi độc đáo thành các chuỗi (và các float không thể được lưu trữ chính xác trong bộ nhớ). – robintw

+0

@robintw nếu bạn cần độ chính xác của dấu phẩy động, hãy xem mô-đun thập phân http://docs.python.org/library/decimal.html – admalledd

+0

@robintw - Tôi chưa thử nghiệm, nhưng tôi tin rằng @admalledd là chính xác. Bạn có thể chọn câu trả lời hoặc chia sẻ cách bạn giải quyết vấn đề không? –

1
+1

Đây là vấn đề phức tạp hơn một chút, bởi vì __hash__ phải trả về một số nguyên. Bạn cần hoặc cần ID nguyên duy nhất cho mỗi điểm (nghĩa là mã và chi phí máy của việc duy trì một đăng ký) hoặc một phép biến đổi số nguyên có thể áp dụng cho '(float, float)' và tạo các số nguyên duy nhất - và tôi một mất mát cho đến với một trong những người ra khỏi đỉnh đầu của tôi. –

+2

@dorkitude: bạn chỉ có thể làm băm (some_float) để chuyển đổi một phao sang một số nguyên duy nhất - sử dụng tích hợp sẵn của Python. –

+0

@josh thật tuyệt! nhưng vấn đề vẫn còn - chúng tôi đang cố gắng chuyển đổi hai phao nổi thành một số nguyên duy nhất. –

10

Thêm một phương pháp băm để lớp Point của bạn:

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

Nói cách khác, các hash của một điểm là một munging của hash của tọa độ x và y.

EDIT: một hàm băm tốt hơn (dựa trên ý kiến ​​ở đây) là:

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

Bởi vì Python băm bản ghi trong một cách mà hash((p,q)) không bằng hash((q,p)), điều này sẽ tránh va chạm băm cho điểm đối xứng về đường chéo .

Sau đó, bạn có thể sử dụng đối tượng Point của bạn như là chìa khóa cho từ điển, đặt chúng trong bộ vv

+0

Nghe có vẻ hay, nhưng vấn đề là tôi không viết lớp Point - nó xuất phát từ API ArcGIS. Có cách nào để 'chèn'/'ghi đè' phương pháp để chèn loại mã băm vào phương pháp? – robintw

+1

@robintw Có: Điểm .__ hash__ = lambda self: return hash (self.x)^băm (self.y) –

+0

@robintw: Ngoài ra, bạn có thể tạo lớp của riêng bạn được phân lớp từ Point: 'class HashPoint (Point): [định nghĩa lớp ...] 'có thể được duy trì nhiều hơn. – senderle

1

Thêm một phương pháp __hash__() đến lớp điểm như Payne nói. Hoặc tự tính toán băm cho mỗi điểm. Trong mọi trường hợp, sử dụng một cái gì đó giống như những gì Python sẽ tự nhiên làm:

... 
def __hash__(self): 
    return hash((self.x, self.y)) 
... 
Các vấn đề liên quan