2016-10-25 6 views
1

異なる長さの一致する整数を含む2つのリストを比較したい。目標は、短いリストの欠損値に基づいて長いリストからアイテムを削除することによって、同じ長さにすることです。リスト:長さと不一致の値が異なる2つのリストを比較する

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] 

一致して返し

これらの2つのリストを不等長で比較し、長いリストで不一致(特定のバリエーション内)を削除するにはどうすればよいですか?

答えて

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

は、線形時間がかかるのソリューションです。他は2次の時間を取るが、あなたの入力が小さければそれだけでよいかもしれない。

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

関連する問題