2015-11-19 67 views
0

我想從列表中獲取子集,方法是檢查其鍵是否在另一個列表中。python通過檢查另一個列表中的鍵來獲取元素

class object: 
    def __init__(self, key, x, y): 
     self.key = key 
     self.x = x 
     self.y = y 

o1 = object(key=300, x=18.0, y=100.0) 
o2 = object(key=301, x=12.0, y=1032.0) 

x1 = object(key=100, x=28.0, y=2300.0) 
x2 = object(key=101, x=43.0, y=332.0) 
... 


myobj = [o1, o2, o3] 
objects = [x1, x2, x3, x4, x5, x6, ... ] 

假設o2.key == x3.keyo3.key == x6.key,然後得到[o2, o3]

有沒有一種簡單的方法來做到這一點?

+0

你能添加確切的數據模型和代碼嗎? – Nat

回答

1

您可以使用以下形式的列表理解:

keys = [ x.key for x in objects ] 
subset = [ x for x in myobj if x.key in keys ] 

雖然你可能會更好調整您的數據轉換成字典,因爲查詢將在更大的數據集有更好的表現。

1

您可以使用列表理解得到的結果

result = [filter(lambda y: y.key == x.key, myobj) for x in objects] 

編輯:

這將返回列表的列表,這是不是anwser OP需要的,它需要一個額外的reduce到faltten結果

def intersect(): 
    o1 = {"key":300, "x":18.0, "y":100.0} 
    o2 = {"key":500, "x":18.0, "y":100.0} 
    o3 = {"key":600, "x":18.0, "y":100.0} 

    x1 = {"key":300, "x":18.0, "y":100.0} 
    x2 = {"key":300, "x":18.0, "y":100.0} 

    myobj = [o1, o2, o3] 
    objects = [x1, x2] 

    result = reduce(lambda x,y: x+y, [filter(lambda y: y['key'] == x['key'], myobj) for x in objects]) 
    print result 
+0

這是O(n^2),'len(objects)* len(myobj)'? – Harvey

+0

已經嘗試過,但結果是'[<0x1916F970過濾對象>,<過濾對象在0x169B1130>]''。 – Deqing

+0

我認爲這會給所需的輸出帶來不同的結果,因爲它實際上會返回列表[[o2],[o3]]而不是[o2,o3](實際上是過濾器對象列表) –

0

你可以添加__hash__()__eq__()方法,對象類型?如果是這樣,你可以直接使用套:

set(myobj).intersection(objects) 

即使你不能使用__hash__(),您可以使用鍵:

subset_keys = set(o.key for o in myobj).intersection(o.key for o in objects) 
subset = [ o for o in objects if o.key in subset_keys ] 

更新:基於更新後的問題...

class object: 
    def __init__(self, key, x, y): 
     self.key = key 
     self.x = x 
     self.y = y 

    def __hash__(self): 
     # must return an int 
     return self.key 
    def __eq__(self, other): 
     return hash(self) == hash(other) 
+1

如果你實現'__hash__',你也應該實現'__eq__',這兩個方法必須一致。 (編輯:看起來像你正在忙着補充,而我正在輸入評論) –

+0

你是對的,我打電話給它。 :)我已經忘記了。 – Harvey

相關問題