2017-03-27 36 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]]