2017-03-27 10 views
0

私はちょっとプログラミングに新しいので、これらのリストの浮動小数点数にはエラーがあるかもしれませんが、Pythonで2つのリストのリストを比較したいと思います。ここでは例:Python - 浮動小数点数に近似したリストのリストの比較

first_list = [['ATOM', 'N', 'SER', -1.081, -16.465, 17.224], 
       ['ATOM', 'C', 'SER', 2.805, -3.504, 6.222], 
       ['ATOM', 'O', 'SER', -17.749, 16.241, -1.333]] 

secnd_list = [['ATOM', 'N', 'SER', -1.082, -16.465, 17.227], 
       ['ATOM', 'C', 'SER', 2.142, -3.914, 6.222], 
       ['ATOM', 'O', 'SER', -17.541, -16.241, -1.334]] 

予想される出力:

Differences = ['ATOM', 'C', 'SER', 2.805, -3.504, 6.222] 

これまでのところ、私のtryings:

def aprox (x, y): 
    if x == float and y == float: 
     delta = 0.2 >= abs(x - y) 
     return delta 
    else: rest = x, y 
    return rest 

def compare (data1, data2): 
    diff = [x for x,y in first_list if x not in secnd_list and aprox(x,y)] + [x for x,y in secnd_list if x not in first_list and aprox(x,y)] 
    return diff 

またはタプルの助けを借りて、しかしそこに私が構築する方法を知りません近似:

def compare (data1, data2): 
    first_set = set(map(tuple, data1)) 
    secnd_set = set(map(tuple, data2)) 
    diff = first_set.symmetric_difference(secnd_set) 
    return diff 

あなたが私を助けることを願っています! :)

+0

あなたの最初の 'compare'関数は、パラメータ' data1'と 'data2'を持っていますが、あなたは(グローバル?)を参照します。 – blacksite

+0

これを試してみようhttp://stackoverflow.com/questions/6105777/how-to-compare-a-list-of-lists-sets-in-python – manvi77

+0

fyi 'isinstance(x、float)'は数字をチェックする方法ですタイプ – ryugie

答えて

4

if x == float and y == float 

が不正確であるライン...変数の型をチェックする 適切な方法は、 は

で上記の行を交換してみてください... type()機能を使用することです
if type(x) is float and type(y) is float: 
0

これはまばたきですが、私はそれを飛行機でやりました。それはあなたに望ましい結果をもたらすはずです。あなたのコードで言及したように、しきい値は0.2に設定されています。これは、2行が返されるべきであることを意味します。

def discrepancies(x, y): 
    for _, (row1, row2) in enumerate(zip(x, y)): 
     for _, (item1, item2) in enumerate(zip(row1[3:],row2[3:])): 
      if abs(item1 - item2) >= 0.2: 
       print row1 
       break 

discrepancies(first_list, secnd_list) 
['ATOM', 'C', 'SER', 2.805, -3.504, 6.222] 
['ATOM', 'O', 'SER', -17.749, 16.241, -1.333] 

カップルの注意事項ループのそれぞれはO(n)を追加し、私はそれが呼ばれると信じてitertools.izip機能を使用することになり、あなたのリスト内の大きなリストのように、これはかなり遅くなります。お役に立てれば!

0

サブエレメントの比較で、両方の各エレメントを繰り返し処理することができます: 次に、いずれのサブエレメントも等しくない場合、そのタイプに応じて結果に追加することができます。つまり、2つの ストリング等しくない場合は、それが結果に追加することができ、またはそれはフロートであり、場合math.isclose()を近似するために使用することができる。

注:修正の3番目の要素に負の符号が欠落している、期待される出力と一致するようになされたfirst_list

import math 

first_list = [['ATOM', 'N', 'SER', -1.081, -16.465, 17.224], 
       ['ATOM', 'C', 'SER', 2.805, -3.504, 6.222], 
       ['ATOM', 'O', 'SER', -17.749, -16.241, -1.333]] # changes made 

secnd_list = [['ATOM', 'N', 'SER', -1.082, -16.465, 17.227], 
       ['ATOM', 'C', 'SER', 2.142, -3.914, 6.222], 
       ['ATOM', 'O', 'SER', -17.541, -16.241, -1.334]] 

diff = [] 
for e1, e2 in zip(first_list, secnd_list): 
    for e_sub1, e_sub2 in zip(e1, e2): 
     # if sub-elements are not equal 
     if e_sub1 != e_sub2: 
      # if it is string and not equal 
      if isinstance(e_sub1, str): 
       diff.append(e1) 
       break # one element not equal so no need to iterate other sub-elements 
      else: # is float and not equal 
       # Comparison made to 0.2 
       if not math.isclose(e_sub1, e_sub2, rel_tol=2e-1): 
        diff.append(e1) 
        break # one element not equal so no need to iterate other sub-elements 
diff 

出力: `オブジェクトfirst_list`と` secnd_list`とパラメータを使用することはありません

[['ATOM', 'C', 'SER', 2.805, -3.504, 6.222]] 
関連する問題