删除列表中的重复项

新手上路,请多包涵

我几乎需要编写一个程序来检查列表是否有任何重复项,如果有,它会删除它们并返回一个新列表,其中包含未重复/删除的项目。这就是我所拥有的,但老实说我不知道该怎么做。

 def remove_duplicates():
    t = ['a', 'b', 'c', 'd']
    t2 = ['a', 'c', 'd']
    for t in t2:
        t.append(t.remove())
    return t

原文由 Neemaximo 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 736
2 个回答

获取唯一项目集合的常用方法是使用 set 。集合是 不同 对象的 无序 集合。要从任何可迭代对象创建集合,您只需将其传递给内置的 set() 函数。如果您以后再次需要真实列表,您可以类似地将集合传递给 list() 函数。

以下示例应涵盖您尝试执行的任何操作:

 >>> t = [1, 2, 3, 1, 2, 3, 5, 6, 7, 8]
>>> list(set(t))
[1, 2, 3, 5, 6, 7, 8]
>>> s = [1, 2, 3]
>>> list(set(t) - set(s))
[8, 5, 6, 7]

从示例结果中可以看出, _原始顺序没有得到维护_。如上所述,集合本身是无序的集合,因此失去了顺序。将集合转换回列表时,会创建任意顺序。

维持秩序

如果顺序对您很重要,那么您将不得不使用不同的机制。一个非常常见的解决方案是依靠 OrderedDict 在插入过程中保持键的顺序:

 >>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]

从 Python 3.7 开始,内置字典也保证保持插入顺序,因此如果您使用的是 Python 3.7 或更高版本(或 CPython 3.6),也可以直接使用它:

 >>> list(dict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]

请注意,这可能会产生一些开销,即首先创建字典,然后从中创建列表。如果您实际上不需要保留顺序,则通常最好使用集合,特别是因为它为您提供了更多操作。查看 此问题 以获取更多详细信息以及在删除重复项时保留顺序的替代方法。


最后请注意, set 以及 OrderedDict / dict 解决方案都要求您的项目是可 _散列的_。这通常意味着它们必须是不可变的。如果您必须处理不可散列的项目(例如列表对象),那么您将不得不使用一种缓慢的方法,在这种方法中,您基本上必须将每个项目与嵌套循环中的每个其他项目进行比较。

原文由 poke 发布,翻译遵循 CC BY-SA 4.0 许可协议

在 Python 2.7 中,从 iterable 中删除重复项同时保持原始顺序的新方法是:

 >>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys('abracadabra'))
['a', 'b', 'r', 'c', 'd']

在 Python 3.5 中,OrderedDict 有一个 C 实现。我的时间表明,这是现在 Python 3.5 的各种方法中最快和最短的。

在 Python 3.6 中,常规 dict 变得既有序又紧凑。 (此功能适用于 CPython 和 PyPy,但可能不会出现在其他实现中)。这为我们提供了一种在保持顺序的同时进行重复数据删除的最快新方法:

 >>> list(dict.fromkeys('abracadabra'))
['a', 'b', 'r', 'c', 'd']

在 Python 3.7 中,保证常规字典在所有实现中都是有序的。 因此,最短和最快的解决方案是:

 >>> list(dict.fromkeys('abracadabra'))
['a', 'b', 'r', 'c', 'd']

原文由 Raymond Hettinger 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题