给出两个相等长度的列表:
_list = [1, 4, 8, 7, 3, 15, 5, 0, 6]
_list2 = [7, 4, 0, 1, 5, 5, 7, 2, 2]
如何尝试获取这样的输出:
output = [(0,3), (1,1), (3,0), (6,4), (6,5), (7,2)]
这里获得了两个列表的交集和共同元素'索引排列在列表中:
output = list of (index of an element in _list, where it appears in _list2)
尝试与集合交集不是一个选项,因为集合删除了重复元素。
答案 0 :(得分:2)
Basic-Intermediate :作为生成器:
def find_matching_indices(a, b):
for i, x in enumerate(a):
for j, y in enumerate(b):
if x == y:
yield i, j
list(find_matching_indices(list1_, list2_))
# [(0, 3), (1, 1), (3, 0), (3, 6), (6, 4), (6, 5), (7, 2)]
Basic-Intermediate :作为列表理解:
[(i, j) for i, x in enumerate(list1_) for j, y in enumerate(list2_) if x == y]
# [(0, 3), (1, 1), (3, 0), (3, 6), (6, 4), (6, 5), (7, 2)]
这些解决方案涉及两个循环。
中级 - 高级:为了好玩,词典是您可能考虑的另一种数据结构:
import collections as ct
import more_itertools as mit
def locate_indices(a, b):
"""Return a dictionary of `a` index keys found at `b` indices."""
dd = ct.defaultdict(list)
for i, y in enumerate(a):
idxs = list(mit.locate(b, lambda z: z == y))
if idxs: dd[i].extend(idxs)
return dd
locate_indices(list1_, list2_)
# defaultdict(list, {0: [3], 1: [1], 3: [0, 6], 6: [4, 5], 7: [2]})
请注意列表a
的索引是字典中的键。列出b
列表中共享相同值的所有索引都将被追加。
使用了defaultdict
,因为它有助于使用列表值构建字典。查看third-party tool more_itertools.locate()
上的更多信息,它只会产生满足lambda条件的所有索引 - 列表a
中的项目也可以在b
中找到。
答案 1 :(得分:2)
from itertools import product
from collections import defaultdict
def mathcing_indices(*lists):
d = defaultdict(lambda: tuple([] for _ in range(len(lists))))
for l_idx, l in enumerate(lists):
for i, elem in enumerate(l):
d[elem][l_idx].append(i)
return sorted([tup for _, v in d.items() for tup in product(*v)])
此解决方案构建一个字典,用于跟踪值在输入列表中显示的索引。因此,如果值5
出现在第一个列表的索引0和2以及第二个列表的索引3中,则字典中5
的值将为([0, 2], [3])
然后使用itertools.product
构建这些索引的所有组合。
这看起来比这里的其他答案更复杂,但因为它是O(nlogn)
而不是O(n**2)
,它是significantly faster,特别是对于大输入。两个长度为1000的随机数列表0-1000使用上述算法在~4秒内完成100次测试,在此使用其他一些时间完成6-13秒
答案 2 :(得分:0)
这是在O(n log n)
中运行的解决方案:
ind1 = numpy.argsort(_list)
ind2 = numpy.argsort(_list2)
pairs = []
i = 0
j = 0
while i<ind1.size and j<ind2.size:
e1 = _list[ind1[i]]
e2 = _list2[ind2[j]]
if e1==e2:
pairs.append((ind1[i],ind2[j]))
i = i + 1
j = j + 1
elif e1<e2:
i = i +1
elif e2<e1:
j = j + 1
print(pairs)