如何在 Python 中删除列表中的重复数据
Aliaksei Yursha
2023年1月30日
2019年12月13日
有时在 Python 中,我们有列表中的值,其中一些是重复的。我们需要从列表中删除所有重复项,以便列表中的所有值都是唯一的。
我们可以使用不同的方法来实现这一点,其中一些方法可以保留元素的原始顺序,而其他方法则不能。
对列表进行重复数据删除而不保留顺序
如果不需要保留原始顺序,则可以使用内置集合 set
数据结构对列表进行重复数据删除。set
作为数据结构,在设计上保证内部元素都是唯一的。
通过从我们的初始列表构造集合 set
,所有重复元素都将被忽略。然后,我们可以将集合转换回列表,并获得唯一元素的列表。
遗憾的是,元素的顺序改变了,因为 set
数据结构的重复数据删除功能是使用哈希表实现的,哈希表不记得首先插入哪个元素。
>>> names = ['Bob', 'Stacy', 'Sarah', 'Jim', 'Stacy', 'Jim']
>>> unique_set = set(names)
>>> unique_list = list(unique_set)
>>> unique_list
['Stacy', 'Sarah', 'Jim', 'Bob']
如果将 NumPy 库用于 Python 中的科学计算,则也可以使用 numpy.unique()
函数。
>>> import numpy
>>> names = ['Bob', 'Stacy', 'Sarah', 'Jim', 'Stacy', 'Jim']
>>> numpy.unique(names).tolist()
['Bob', 'Jim', 'Sarah', 'Stacy']
请注意,上述方法也不会保留原始元素顺序。保留顺序的 NumPy
方式更多,你可以在下面找到。
使用保留顺序对列表进行重复数据删除
一种允许保留初始顺序的简单解决方案是使用双 for-each
循环。
第一个循环遍历原始列表的所有元素。第二个循环检查我们是否已经遍历到具有相同值的元素。
如果还没有,则将其添加到 unique
列表中,最后将按原始顺序包含唯一元素。
>>> names = ['Bob', 'Stacy', 'Sarah', 'Jim', 'Stacy', 'Jim']
>>> unique = []
>>> for name in names: # 1st loop
... if name not in unique: # 2nd loop
... unique.append(name)
...
>>> unique
['Bob', 'Stacy', 'Sarah', 'Jim']
在保留原始顺序的同时对列表进行重复数据删除的另一种方法是使用 collections.OrderedDict
数据结构。OrderedDict
是 Python 中一种特殊的字典数据结构,它可以记住键插入的顺序。
>>> from collections import OrderedDict
>>> names = ['Bob', 'Stacy', 'Sarah', 'Jim', 'Stacy', 'Jim']
>>> unique = list(OrderedDict.fromkeys(names))
>>> unique
['Bob', 'Stacy', 'Sarah', 'Jim']
如果你使用 Python Pandas 数据分析库,也可以用 pandas.unique
函数。此方法是保留顺序的。
>>> import pandas
>>> names = ['Bob', 'Stacy', 'Sarah', 'Jim', 'Stacy', 'Jim']
>>> pandas.unique(names).tolist()
['Bob', 'Stacy', 'Sarah', 'Jim']
NumPy 在保留顺序的同时对列表进行重复数据删除的方法要复杂一些。你必须记住每个不同元素的索引,然后使用此类索引从原始元素重新创建一个唯一列表。
>>> import numpy
>>> names = ['Bob', 'Stacy', 'Sarah', 'Jim', 'Stacy', 'Jim']
>>> _, indexes = numpy.unique(names, return_index=True)
>>> unique = [names[i] for i in numpy.sort(indexes)]
>>> unique
['Bob', 'Stacy', 'Sarah', 'Jim']