我有两个列表,都很长。列表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将是列表列表。
答案 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)
使用dict
或defaultdict
将唯一值存储为映射到它们出现的索引的键,然后合并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])
这会对每个A
和B
进行一次迭代,因此即使它们是一次性使用迭代器,它也能正常工作,例如:从类似文件的对象开始,它可以高效工作,不再存储超出需要的数据,并坚持使用廉价的基于哈希的操作而不是重复迭代。
这不是您特定问题的解决方案,但它保留了解决问题所需的所有信息,然后保留了一些信息(例如,找出{{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