2016-10-25 161 views
1

我想比較兩個包含不同長度匹配整數的列表。目標是通過基於較短列表中的缺失值從較長列表中移除項目來使它們具有相同的長度。列表:比較兩個不等長和不匹配值的列表

list1 = [101, 201, 301, 402, 502, 603, 701, 802, 904, 10012, 10021, 10033, 10041, 10054, 10062, 10071, 10082, 10093, 10101] 
list2 = [102, 203, 504, 601, 703, 901, 10013, 10071, 10082, 10093, 10103] 

但是,兩個列表中的匹配值不完全相同,並且在此示例中可以在0和3之間變化。

結果是這樣的:

resultlist1 = [101, 201, 502, 603, 701, 904, 10012, 10073, 10082, 10093, 10101] 
resultlist2 = [102, 203, 504, 601, 703, 901, 10013, 10071, 10082, 10093, 10103] 

removed_items_list1 = [2, 3, 7, 10, 11, 12, 13, 14] # Index numbers of 

我嘗試沒有成功以下

set(list1).intersection(list2) 

只返回精確匹配

for i in xrange(len(list2)): 
    if abs(list1[i] - list2[i]) > 3: 
     del list1[i] 

不會刪除所有不需要的值

如何比較這兩個不等長的列表並刪除較長列表中的不匹配(在某個變體內)?

回答

0

可以使用numpy的陣列比較:

list1 = [101, 201, 301, 402, 502, 603, 701, 802, 904, 10012, 10021, 10033, 10041, 10054, 10062, 10071, 10082, 10093, 10101] 
list2 = [102, 203, 504, 601, 703, 901, 10013, 10071, 10082, 10093, 10103] 
import numpy as np 
l1 = np.array(list1) 
l2 = np.array(list2) 

ind = abs(l1 - l2[:,None]) <= 3 

print l1[ind.max(0)] 
print l2[ind.max(1)] 
print ind.max(1) 
print ind.max(0) 
print np.where(~(ind.max(0))) 

導致

[ 101 201 502 603 701 904 10012 10071 10082 10093 10101] 

[ 102 203 504 601 703 901 10013 10071 10082 10093 10103] 

[ True True True True True True True True True True True] 

[ True True False False True True True False True True False False 
False False False True True True True] 

(array([ 2, 3, 7, 10, 11, 12, 13, 14]),) 
1

這裏是一個解決方案,將線性時間;其他人需要二次時間,儘管如果你的輸入很小,這可能會很好。

def align(shorter, longer, margin=3):  
    result = [] 
    removed = [] 

    longer = enumerate(longer) 

    for target in shorter: 
     while True: 
      index, current = next(longer) 
      if abs(current - target) <= margin: 
       result.append(current) 
       break 
      else: 
       removed.append(index) 

    return result, removed 

這假設您可以隨時按照您的示例對齊列表。如果不是這樣,你需要在上面添加一些錯誤檢查。

實施例:

>>> align(list2, list1) 
([101, 201, 502, 603, 701, 904, 10012, 10071, 10082, 10093, 10101], 
[2, 3, 7, 10, 11, 12, 13, 14]) 
+0

線性仍然可以採取比平方爲一定的長度更長。因此,比較不同方法的表現會是有趣的,如果有人有時間:) – dnalow

+0

非常真實,因此「如果輸入很小」免責聲明。但是最終,列表理解僅比Python中等價的for循環更快,所以上述解決方案的隱藏常量至少可以與理解解決方案的常量相媲美。我沒有任何測試,但我的猜測是,當名單長達幾百條時,你會開始看到真正的差異。 – jme

+0

我喜歡你的解決方案。我使用了大約1200個條目的列表。但是,當我使用你的函數,我得到一個StopIteration錯誤: index,current = next(longer) – cf2

相關問題