2017-06-23 51 views
-1

如果我將某些點的(x,y,z)座標保存在python集合中('coord'),我可以非常容易地檢查點屬於集合做定義一個運算符「距離」而不是運算符「in」與Python集合

(X,Y,Z) in coord 

但如果我的座標是實數,我必須有確切的實際數字爲一場比賽。

F = (0.0, 1.1, 2.0) 
coordinates.add(F) 
G = (0.0, 1.100000000001, 2.0) 
G in coordinates 
False 

有沒有一種方法來定義使用距離標準而不是平等標準的'in'運算符?因爲我會知道如何使用for循環來做到這一點,但in運算符是如此之快......

+3

「因爲我知道如何用for循環做這件事,但in運算符非常快」 - 帶有集合的'in'基於散列表查找,這對於查找附近的點不起作用。如果這是你想要做的,那麼一組可能不是一個合適的數據結構。 – user2357112

+1

'in'快速取決於你使用它的方式;你可以爲*語法*實現'__contains__',但它可能仍然有相同的循環內部。 – jonrsharpe

+0

你很可能想要寫一個函數來確定點是否在座標中,比如'isXinY = lambda x,y:any([((x [0] -i [0])** 2 +(x [1] -i [1])** 2+(x [2] -i [2])** 2)** 0.5 < for i in y])' – victor

回答

1

您可以實現這一點相當簡單。

使用向量邏輯以比較兩點:

def fuzzy_eq(A, B): 
    EPS = 0.01 

    # first, find a delta between two points 
    x = A[0] - B[0] 
    y = A[1] - B[1] 
    z = A[2] - B[2] 

    # next, find the length of that delta 
    length = sqrt(x*x + y*y + z*z) 

    # finally, check the length 
    return length < EPS: 

但它會更容易一些3D矢量圖庫很多:

def fuzzy_eq(A, B): 
    EPS = 0.01 

    # assuming A and B are of some 3D vector class 
    length = (A-B).length() 
    return length < EPS 

實現的,而不是in運營商自己的函數:

def fuzzy_in(coords, X): 
    return any(fuzzy_eq(coord, X) for coord in coords) 

fuzzy_in(coordinates, G) 

要用你的方式使用in操作符,你應該子集(或其他類似容器),並覆蓋__contains__方法:

class Coordinates(set): 

    def __contains__(self, value): 
     return fuzzy_in(self, value) 

此外,作爲@ user2357112指出的那樣,你可能不需要這種情況下的組。

如果你的目標是速度,而你已經有問題,你應該使用其他語言。或者一些使用C的快速庫,例如,它可以處理較慢的部分。