首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python列表交叉效率:生成器还是过滤器()?

Python列表交叉效率:生成器还是过滤器()?
EN

Stack Overflow用户
提问于 2011-06-16 09:13:56
回答 4查看 14.7K关注 0票数 15

我想在Python (2.7)中交叉两个列表。我需要结果是可迭代的:

代码语言:javascript
复制
list1 = [1,2,3,4]
list2 = [3,4,5,6]
result = (3,4) # any kind of iterable

提供完整的迭代将首先在交集之后执行,以下哪一项更有效?

使用生成器:

代码语言:javascript
复制
result = (x for x in list1 if x in list2)

使用过滤器():

代码语言:javascript
复制
result = filter(lambda x: x in list2, list1)

其他建议?

提前谢谢你,

安农

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-06-16 09:16:52

这两个都没有。最好的方法是使用集合。

代码语言:javascript
复制
list1 = [1,2,3,4]
list2 = [3,4,5,6]
result = set(list1).intersection(list2)

集合是可迭代的,因此不需要将结果转换为任何内容。

票数 30
EN

Stack Overflow用户

发布于 2011-06-16 09:16:59

您的解决方案的复杂性为O(m*n),其中mn分别是两个列表的长度。可以通过为其中一个列表设置一组来提高O(m+n)的复杂性:

代码语言:javascript
复制
s = set(list1)
result = [x for x in list2 if x in s]

在速度比可读性更重要的情况下(也就是说,几乎从不),您也可以使用

代码语言:javascript
复制
result = filter(set(a).__contains__, b)

这比我的机器上的其他解决方案快20 %。

票数 8
EN

Stack Overflow用户

发布于 2019-11-17 04:22:45

我试着比较三种列表交叉口方法的速度:

代码语言:javascript
复制
import random

a = [random.randint(0, 1000) for _ in range(1000)]
b = [random.randint(0, 1000) for _ in range(1000)]

解决方案1:列表理解

时间流逝:8.95265507698059

代码语言:javascript
复制
import time
start = time.time()
for _ in range(1000):
    result = [x for x in a if x in b]
elapse = time.time() - start
print(elapse) 

解决方案2:设置

时间流逝:0.09089064598083496

代码语言:javascript
复制
start = time.time()
for _ in range(1000):
    result = set.intersection(set(a), set(b))
elapse = time.time() - start
print(elapse) 

解决方案3: numpy.intersect1d

时间流逝:0.323300838470459

代码语言:javascript
复制
start = time.time()
for _ in range(1000):
    result = np.intersect1d(a, b)
elapse = time.time() - start
print(elapse) 

结论

我认为使用set.intersection是最快的方法。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6369527

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档