比较两个不等长和不匹配值的列表

时间:2016-10-25 14:36:00

标签: python list

我想比较两个包含不同长度匹配整数的列表。目标是通过根据较短列表中的缺失值从较长列表中删除项目,使它们具有相同的长度。清单:

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 :(得分: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])

答案 1 :(得分: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]),)