【问题标题】:Fastest Way To Remove Duplicates In Lists Python删除列表中重复项的最快方法 Python
【发布时间】:2010-12-13 02:49:05
【问题描述】:

我有两个非常大的列表,循环一次至少需要一秒钟,我需要循环 200,000 次。删除两个列表中的重复项以形成一个列表的最快方法是什么?

【问题讨论】:

  • 您的计时表明目前一个循环需要 55 小时。听到提议的解决方案需要多长时间会很有趣。

标签: python list sorting


【解决方案1】:

这是我能想到的最快的方法:

import itertools
output_list = list(set(itertools.chain(first_list, second_list)))

轻微更新:正如jcd 指出的那样,根据您的应用程序,您可能不需要将结果转换回列表。由于集合本身是可迭代的,因此您可以直接使用它:

output_set = set(itertools.chain(first_list, second_list))
for item in output_set:
    # do something

请注意,任何涉及使用set() 的解决方案都可能会重新排序列表中的元素,因此无法保证元素会按任何特定顺序排列。也就是说,由于您正在组合两个列表,因此很难找到一个充分的理由说明您需要对它们进行特定排序,所以这可能不是您需要担心的事情。

【讨论】:

  • 哦,你的解决方案比我的好:)
  • 感谢大家的回答,他们都帮了大忙! :)
  • +1。如果顺序 很重要,那么也许一个有序集合就可以了:stackoverflow.com/questions/1653970/…
  • @Stephan202:好点。但是,我认为切换到有序集合(使用任何实现,尤其是纯 Python 实现)会比无序(基于哈希表)集合慢得多。根据列表的大小以及散列函数对项目的执行情况,使用普通的set 然后对项目进行排序可能会更快。
【解决方案2】:
result = list(set(list1).union(set(list2)))

我就是这样做的。不过,我不太确定性能,但肯定比手动操作要好。

【讨论】:

  • set.union(self, other) 适用于任何可迭代为 other
【解决方案3】:

正如丹尼尔所说,一个集合不能包含重复的条目 - 所以连接列表:

list1 + list2

然后将新列表转换为集合:

set(list1 + list2)

然后回到一个列表:

list(set(list1 + list2))

【讨论】:

  • 感谢您解释我的代码在做什么。打败我吧! :-) 我只是提到我编辑我的答案以使用itertools.chain() 而不是仅仅连接列表的原因是因为它避免了在内存中分配第三个大列表。 set() 构造函数实际上并不需要一个列表,它只需要一个可以迭代所有元素的可迭代对象,而 itertools.chain() 可以更有效地做到这一点(通过避免复制)。
【解决方案4】:

我会推荐这样的东西:

def combine_lists(list1, list2):
    s = set(list1)
    s.update(list2)
    return list(s)

这消除了创建前两个串联的怪物列表的问题。

根据您对输出的处理方式,不必费心转换回列​​表。如果订购很重要,您可能需要一些装饰/排序/取消装饰的恶作剧。

【讨论】:

  • 同意,没有必要连接两个列表——这只会浪费内存。我很想看看调用s.update(list2) 与我上面使用的迭代器方法之间的性能差异。您的方法可能会稍微快一些。但是,正如您所指出的,您只需在最后不转换回列表即可获得更大的性能节省。
  • 我跑了几个 timeit,它似乎有所不同,哪个更快,但从来没有超过 5% 或 10%。我称之为平局。
  • 鉴于 itertools 只链接两个对象,我想说它的影响非常小,所以问题是 set()ing 一个大列表或 set()ing 之间是否存在显着差异该列表的一半和 .update() 其余部分。好像没有。
猜你喜欢
  • 1970-01-01
  • 2015-10-07
  • 2010-11-23
  • 2016-09-06
  • 2018-05-07
  • 2015-11-27
  • 2015-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多