在列表中删除重复项
在Python 2.7中,从可迭代对象中删除重复项并保持其原始顺序的新方法是:
>>> 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中,常规dict保证在所有实现中都有序。 因此,最短和最快的解决方案是:
>>> list(dict.fromkeys('abracadabra')) ['a', 'b', 'r', 'c', 'd']
获取唯一项的常用方法是使用 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
解决方案都需要您的项是可哈希的。这通常意味着它们必须是不可变的。如果您需要处理不可哈希的项(例如列表对象),那么您将不得不使用一个缓慢的方法,基本上您将不得不在嵌套循环中将每个项与每个其他项进行比较。