将两个列表相交并计算每个元素重叠的次数

Intersect two lists and count how many times each element overlaps

我使用以下代码将两个列表相交:

def interlist(lst1,lst2): 
    lst3 = list(filter(lambda x: x in lst1, lst2))

    return lst3

问题是,我想计算 lst1lst2 之间的每个交叉点。结果应该是一个字典,将元素映射到它们在两个列表中的重叠次数。

这是一个使用 collections.Counter 并设置交集的简单解决方案。这个想法是首先分别计算每个列表中每个元素的出现次数;然后,对于每个元素,重叠数是两个计数的 min。这会将一个列表中的每个匹配项与另一个列表中的单个匹配项匹配,因此 min 给出了可以匹配的次数。我们只需要计算出现在两个列表中的元素,所以我们取两个键集的交集。

如果您想计算所有匹配对(即 lst1 中的每个匹配项都与 lst2 中的每个匹配项匹配),请将 min(c1[k], c2[k]) 替换为 c1[k] * c2[k]。这计算了从 lst1 中出现一次和从 lst2.

中选择一对的方式的数量
from collections import Counter

def count_intersections(lst1, lst2):
    c1 = Counter(lst1)
    c2 = Counter(lst2)
    return { k: min(c1[k], c2[k]) for k in c1.keys() & c2.keys() }

示例:

>>> lst1 = ['a', 'a', 'a', 'b', 'b', 'c', 'e']
>>> lst2 = ['a', 'b', 'b', 'b', 'd', 'e']
>>> count_intersections(lst1, lst2)
{'b': 2, 'a': 1, 'e': 1}

此解决方案运行时间为 O(m + n) 并且最多使用 O(m + n) 辅助 space,其中 m 和 n 是两个列表的大小。

根据您的说明:

如果lst1 = ["a", "b", "c"]lst2 = ["a", "a", "a", "b", "b"]然后output = {"a": 3, "b": 2},你可以简单地做:

output = {}
for x in set(lst1):
    cnt = lst2.count(x)
    if cnt > 0:
        output[x] = cnt