2017-03-27 64 views
0

我有點新來編程,我想比較兩個列表中的列表,而這些列表中的浮點數可能有錯誤。下面一個例子: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',但你引用(全球?)對象'first_list'和'secnd_list'從不使用的參數。 – 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處設置了閾值,這意味着應該返回兩行,而不是像你提到的那樣。

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] 

夫婦的注意事項,這將讓每個for循環非常慢加O(n)和你的列表中的大名單我會用itertools.izip功能,我相信它叫。希望這可以幫助!

0

也許你可以遍歷兩個元素,然後比較子元素: 然後,當任何子元素不相等時,它可以被添加到結果取決於它的類型,即如果兩個 字符串是不相等時,它可以被添加到結果,或者如果它是浮動和math.isclose()可以用於近似:

注:校正是爲了期望的輸出相匹配,還有中缺少的第三元件負號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 

輸出:

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