匹配Python中列表之间的元素 - 保持位置

时间:2016-08-09 14:39:46

标签: python list iterator match

我有两个列表,都很长。列表A包含一个整数列表,其中一些在列表B中重复。我可以通过使用以下内容找到两者中出现的元素:

idx = set(list_A).intersection(list_B)

这将返回列表A和列表B中出现的所有元素的集合。

但是,我想找到一种方法来查找两个列表之间的匹配,并保留有关元素的信息。两个名单中的职位。这样的功能可能如下:

def match_lists(list_A,list_B):
.
.
.
return match_A,match_B

其中match_A将包含list_A中在list_B中某处匹配的元素的位置,反之亦然。 我可以看到如何使用for循环构造这样的列表,但是对于长列表来说这感觉会非常慢。

关于重复:list_B没有重复项,如果list_A中有重复项,则将所有匹配的位置作为列表返回,因此match_A将是列表列表。

5 个答案:

答案 0 :(得分:3)

那应该做的工作:)

def match_list(list_A, list_B):
    intersect = set(list_A).intersection(list_B)
    interPosA = [[i for i, x in enumerate(list_A) if x == dup] for dup in intersect]
    interPosB = [i for i, x in enumerate(list_B) if x in intersect]
    return interPosA, interPosB

(感谢机器渴望重复编辑)

答案 1 :(得分:2)

使用dictdefaultdict将唯一值存储为映射到它们出现的索引的键,然后合并dicts

from collections import defaultdict

def make_offset_dict(it):
    ret = defaultdict(list)  # Or set, the values are unique indices either way
    for i, x in enumerate(it):
        ret[x].append(i)

dictA = make_offset_dict(A)
dictB = make_offset_dict(B)
for k in dictA.viewkeys() & dictB.viewkeys():  # Plain .keys() on Py3
    print(k, dictA[k], dictB[k])

这会对每个AB进行一次迭代,因此即使它们是一次性使用迭代器,它也能正常工作,例如:从类似文件的对象开始,它可以高效工作,不再存储超出需要的数据,并坚持使用廉价的基于哈希的操作而不是重复迭代。

这不是您特定问题的解决方案,但它保留了解决问题所需的所有信息,然后保留了一些信息(例如,找出{{1}中任何给定值的匹配位置都很便宜}或A);你可以轻松地将它适应你的用例或更复杂的用例。

答案 2 :(得分:1)

这个怎么样:

def match_lists(list_A, list_B):
    idx = set(list_A).intersection(list_B)
    A_indexes = []
    for i, element in enumerate(list_A):
        if element in idx:
            A_indexes.append(i)
    B_indexes = []
    for i, element in enumerate(list_B):
        if element in idx:
            B_indexes.append(i)
    return A_indexes, B_indexes

答案 3 :(得分:0)

这只会在每个列表中运行一次(只需要一个dict),也可以在list_B中使用重复项

def match_lists(list_A,list_B):
    da=dict((e,i) for i,e in enumerate(list_A))
    for bi,e in enumerate(list_B):
        try:
            ai=da[e]        
            yield (e,ai,bi) # element e is in position ai in list_A and bi in list_B
        except KeyError:
            pass

答案 4 :(得分:-1)

试试这个:

def match_lists(list_A, list_B):
    match_A = {}
    match_B = {}
    for elem in list_A:
        if elem in list_B:
            match_A[elem] = list_A.index(elem)
            match_B[elem] = list_B.index(elem)

    return match_A, match_B