查找列表交集中元素数量的快速方法(Python)

查找列表交集中元素数量的快速方法(Python),python,optimization,Python,Optimization,在Python中有没有更快的方法来计算此值: len([x for x in my_list if x in other_list]) 我尝试使用集合,因为列表的元素是唯一的,但我没有注意到任何区别 len(set(my_list).intersection(set(other_list))) 我在处理大名单,所以即使是最轻微的改进也很重要。 谢谢我认为像这样的生成器表达式会很快 sum(1 for i in my_list if i in other_list) 否则,集合交叉口的速度将

在Python中有没有更快的方法来计算此值:

len([x for x in my_list if x in other_list])
我尝试使用集合,因为列表的元素是唯一的,但我没有注意到任何区别

len(set(my_list).intersection(set(other_list)))
我在处理大名单,所以即使是最轻微的改进也很重要。
谢谢

我认为像这样的生成器表达式会很快

sum(1 for i in my_list if i in other_list)
否则,
集合
交叉口的速度将与它所能达到的速度一样快

len(set(my_list).intersection(other_list))

其思想是首先对两个列表进行排序,然后像我们希望合并它们一样遍历它们,以便找到第一个列表中也属于第二个列表的元素。这样我们就有了一个
O(nlogn)
算法

def mycount(l, m):
    l.sort()
    m.sort()
    i, j, counter = 0, 0, 0
    while i < len(l) and j < len(m):
        if l[i] == m[j]:
            counter += 1
            i += 1
        elif l[i] < m[j]:
            i += 1
        else:
            j += 1
    return counter
同样,我们可以使用计数器:

from collections import Counter
def mycount(l, m):
    c = Counter(l)
    c.update(m)
    return sum(v == 2 for v in c.itervalues())
从中,两组
s
t
的集合交点具有时间复杂性:

平均值-O(最小值(长(s)、长(t))

最差-O(长(s)*长(t))

len([x代表我的列表中的x,如果x代表其他列表中的x])
的复杂性为O(n^2),这相当于
set.intersection()的最坏情况

如果使用
set.intersection()
,则只需先将其中一个列表转换为集合:


所以
len(set(my_list)。intersection(other_list))
平均来说应该比嵌套列表理解更快。

简单的方法是找到最小长度的列表…而不是将其与
set.intersection一起使用,例如:

a = range(100)
b = range(50)

fst, snd = (a, b) if len(a) < len(b) else (b, a)
len(set(fst).intersection(snd))
a=范围(100)
b=范围(50)
fst,snd=(a,b)如果len(a)
您可以尝试使用
过滤器
功能。因为您提到您正在处理大量列表,
itertools
模块的
ifilter
将是一个不错的选择:

from itertools import ifilter
my_set = set(range(100))
other_set = set(range(50))
for item in ifilter(lambda x: x in other_set, my_set):
    print item

设置转换的列表不是比我得到的改进更耗时吗?你必须确定它的时间。转换本身需要时间,但它会通过使other_list中的
x
操作快得多来弥补自己。这些操作不同:第一个是两个列表的交集,即second是区别。你是对的,这是一个愚蠢的错误。集合解决方案将是
len(集合(我的列表)。intersection(集合(其他列表))
你正在执行两个排序操作-然后在检索长度时重复:)-然后我停止阅读…你寻找较短的列表以加快列表到设置转换的速度?@nick你只需要“唯一”第一个列表与较长的列表相交-你只需要其中一个列表中的唯一值,就可以使其作为
集运行,因为
。相交
会占用任何可编辑的。。。因此,如果第一个列表只有两个唯一值(比如说),那么如果对应的列表有数百万个值(比如说)@nick当然,如果你碰巧知道一个列表比另一个列表的唯一性,那么这是一种幼稚的方法,但通常比将两者转换为
set
s aprior要好
from itertools import ifilter
my_set = set(range(100))
other_set = set(range(50))
for item in ifilter(lambda x: x in other_set, my_set):
    print item