Python:如何从列表中删除所有重复的项目

Python: How to remove all duplicate items from a list

本问题已经有最佳答案,请猛点这里访问。

如何使用python检查列表并删除所有重复项?我不想指定重复项是什么——我想让代码找出是否有重复项,如果有,则删除它们,只保留每个重复项的一个实例。如果列表中有多个重复项,它也必须工作。

例如,在下面的代码中,列表lsparatedorblist有12个项-一个重复6次,一个重复5次,只有一个实例。我希望它改变列表,这样就只有三个项目——每个项目中的一个,并且按照它们之前出现的顺序排列。我试过这个:

1
2
3
4
for i in lseparatedOrbList:
   for j in lseparatedOrblist:
        if lseparatedOrbList[i] == lseparatedOrbList[j]:
            lseparatedOrbList.remove(lseparatedOrbList[j])

但我得到了错误:

1
2
3
4
Traceback (most recent call last):
  File"qchemOutputSearch.py", line 123, in <module>
    for j in lseparatedOrblist:
NameError: name 'lseparatedOrblist' is not defined

我猜是因为我在循环遍历lsepartedorblist的时候试图循环它,但是我想不出其他的方法。


只需创建一个要填充的新列表,如果列表中的项目还没有在新列表中输入,否则只需继续到原始列表中的下一个项目。

1
2
3
for i in mylist:
  if i not in newlist:
    newlist.append(i)

我认为这是正确的语法,但是我的Python有点不稳定,我希望你至少能理解这个想法。


使用set()

1
woduplicates = set(lseparatedOrblist)

返回一个没有重复项的集。如果出于某种原因,您需要返回列表:

1
woduplicates = list(set(lseperatedOrblist))

但是,这将与原始列表的顺序不同。


你可以这样做:

1
x = list(set(x))

示例:如果您执行类似的操作:

1
2
3
x = [1,2,3,4,5,6,7,8,9,10,2,1,6,31,20]
x = list(set(x))
x

您将看到以下结果:

1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 31]

您只需要考虑一件事:结果列表将不会作为原始列表进行排序(将在流程中丢失顺序)。


这应该更快,并且将保留原始顺序:

1
2
seen = {}
new_list = [seen.setdefault(x, x) for x in my_list if x not in seen]

如果您不关心订单,您可以:

1
new_list = list(set(my_list))


不,这只是一个打字错误,末尾的"列表"必须大写。您可以在同一个变量上嵌套循环(尽管很少有好的理由)。

但是,代码还有其他问题。首先,您要遍历列表,所以ij将是项目而不是索引。此外,在对集合进行迭代时不能更改它(好吧,您"可以"运行它,但疯狂是这样的——例如,您可以跳过项)。然后是复杂度问题,您的代码是O(n^2)。或者将列表转换为set并返回到list中(简单,但对其余列表项进行无序处理),或者执行如下操作:

1
2
3
4
5
6
7
seen = set()
new_x = []
for x in xs:
    if x in seen:
        continue
    seen.add(x)
    new_xs.append(x)

这两种解决方案都要求项目是可哈希的。如果这是不可能的,你可能会坚持你目前的方法,而没有提到的问题。


这应该为您做到:

1
new_list = list(set(old_list))

set将自动删除重复项。list将把它重新放到一个列表中。


最简单的方法是使用set()函数:

1
new_list = list(set(your_list))

实际上,这是因为你缺少一个大写字母。

目的明确:

1
2
for i in lseparatedOrbList:   # capital 'L'
for j in lseparatedOrblist:   # lowercase 'l'

虽然更有效的方法是将内容插入到set中。

如果维护列表顺序很重要(即必须"稳定"),请查看此问题的答案。


不可删除的列表。它更快,因为它不会迭代已经检查过的条目。

1
2
3
4
5
6
def purge_dublicates(X):
    unique_X = []
    for i, row in enumerate(X):
        if row not in X[i + 1:]:
            unique_X.append(row)
    return unique_X

使用集

1
return list(set(result))

使用DICT

1
return dict.fromkeys(result).keys()

维持秩序的现代方法是:

1
2
>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys(lseparatedOrbList))

正如RaymondHettinger(python core dev)在这个答案中所讨论的。在python 3.5及更高版本中,这也是最快的方法——有关详细信息,请参见链接的答案。但是,这些键必须是可哈希的(我认为您列表中的情况也是如此)


这样可以删除列表中多次出现的特定项:尝试删除所有5个

1
2
3
4
5
6
7
list1=[1,2,3,4,5,6,5,3,5,7,11,5,9,8,121,98,67,34,5,21]
print list1
n=input("item to be deleted :" )
for i in list1:
    if n in list1:
        list1.remove(n)
print list1

有一种更快的方法可以解决这个问题:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
list = [1, 1.0, 1.41, 1.73, 2, 2, 2.0, 2.24, 3, 3, 4, 4, 4, 5, 6, 6, 8, 8, 9, 10]
list2=[]

for value in list:
    try:
        list2.index(value)
    except:
        list2.append(value)
list.clear()
for value in list2:
    list.append(value)
list2.clear()
print(list)
print(list2)