首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么使用字典从一个列表中排除另一个列表的速度要快得多?

为什么使用字典从一个列表中排除另一个列表的速度要快得多?
EN

Stack Overflow用户
提问于 2013-02-22 21:59:07
回答 3查看 133关注 0票数 1

令我惊讶的是,在两种方法中,排除一个元组列表与另一个元组列表的速度有多么不同。所以我想知道为什么。

我有一个包含1,500个元组的列表,其形式为(int,float ),按元组的值排序。(补充说明:元组列表中的每个int值都是不同的。)我想找出排除子列表的最快方法。所以首先我创建了一个子列表来排除:

代码语言:javascript
复制
exclude_list = [v for i,v in enumerate(tuple_list) if (i % 3) == 0]

然后,我选择了两种不同的方法从tuple_list中删除exclude_list (但这不是我最终确定的两种方法):

代码语言:javascript
复制
remainder_list = [v for v in tuple_list if v not in exclude_list]

和,

代码语言:javascript
复制
remainder_set = set(tuple_list) - set(exclude_list)
remainder_list = sorted(remainder_set, key=itemgetter(1)) #edited to chance key to 1 from 0

时间上的差异是巨大的:第一种方法为14.7235秒(500次),第二种方法为0.3426秒(500次)。我理解为什么这两种方法有如此不同的时间,因为第一种方法需要搜索主列表中的每一项的sub_list。因此,我想出了一个更好的搜索/排除方法:

代码语言:javascript
复制
exclude_dict = dict(exclude_list)
remainder_list = [v for v in tuple_list if v[0] not in exclude_dict]

我不认为这个版本的排除列表项会比第一个版本快很多。它不仅比第一种方法快,而且比第二种方法更快!它的时间是0.11177 (500次)。为什么这比我的set-difference/resort方法更快?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-02-22 22:01:30

列表的in运算符的计算复杂度为O(N)。它只做一个线性搜索。要做得更好,您可以将exclude_list更改为exclude_set

代码语言:javascript
复制
exclude_set = {v for i,v in enumerate(tuple_list) if (i % 3) == 0}

或者,如果您已经有exclude_list

代码语言:javascript
复制
exclude_set = set(exclude_list)

然后像以前一样计算你的remainder_list

代码语言:javascript
复制
remainder_list = [v for v in tuple_list if v not in exclude_set]

这是更好的WAY,因为集合的in是一个非常令人印象深刻的O(1) (平均)。在这里,您也不需要对remainder_list进行重新排序,因此删除了O(MlogM)步骤(其中M == len(remainder_list)。

当然,通过这个简单的例子,我们可以用一个list-comp来构造整个东西:

代码语言:javascript
复制
remainder_list = [v for i,v in enumerate(tuple_list) if (i % 3) != 0]     
票数 2
EN

Stack Overflow用户

发布于 2013-02-22 22:07:21

您可能需要检查time complexity of list and set operations

代码语言:javascript
复制
remainder_list = [v for v in tuple_list if v not in exclude_list] 

这里的in操作是O(N),它检查tuple_list中的所有元素,看看exclude_list中是否存在该元素。所以它的复杂性是O(len(tuple_list) * len(exclude_list))

集合上的差分-操作的复杂度为O(n),因为集合使用哈希表作为其底层数据结构,并且具有O(1)成员关系检查。因此,这行代码如下:

代码语言:javascript
复制
remainder_set = set(tuple_list) - set(exclude_list).

具有O(len(tuple_list))复杂性。

票数 3
EN

Stack Overflow用户

发布于 2013-02-22 22:10:38

你们的算法不是等同的。你们的元素是情侣。使用前两种方法,您可以通过匹配对来排除元素。使用第三种方法(使用dict),您可以排除仅比较情侣中的第一个元素的元素。

如果配对没有多少不同的第一个元素,那么dict方法要快得多,但结果可能不同。

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

https://stackoverflow.com/questions/15025878

复制
相关文章

相似问题

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