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

Python 如何从列表中删除所有重复项,python,list,Python,List,如何使用python检查列表并删除所有重复项?我不希望必须指定重复项是什么-我希望代码能够找出是否有重复项,如果有,则将其删除,每个重复项只保留一个实例。如果一个列表中有多个重复项,它也必须起作用 例如,在我下面的代码中,列表lseparatedOrbList有12项-一项重复六次,一项重复五次,并且只有一个实例。我想让它改变列表,这样就只有三个项目——每个项目一个,并且它们的出现顺序与之前相同。我试过这个: for i in lseparatedOrbList: for j in lse

如何使用python检查列表并删除所有重复项?我不希望必须指定重复项是什么-我希望代码能够找出是否有重复项,如果有,则将其删除,每个重复项只保留一个实例。如果一个列表中有多个重复项,它也必须起作用

例如,在我下面的代码中,列表lseparatedOrbList有12项-一项重复六次,一项重复五次,并且只有一个实例。我想让它改变列表,这样就只有三个项目——每个项目一个,并且它们的出现顺序与之前相同。我试过这个:

for i in lseparatedOrbList:
   for j in lseparatedOrblist:
        if lseparatedOrbList[i] == lseparatedOrbList[j]:
            lseparatedOrbList.remove(lseparatedOrbList[j])
但我得到了一个错误:

Traceback (most recent call last):
  File "qchemOutputSearch.py", line 123, in <module>
    for j in lseparatedOrblist:
NameError: name 'lseparatedOrblist' is not defined
回溯(最近一次呼叫最后一次):
文件“qchemOutputSearch.py”,第123行,在
对于lseparatedOrblist中的j:
名称错误:未定义名称“lseparatedOrblist”
我猜是因为我在循环lseparatedOrbList时试图循环lseparatedOrbList,但我想不出其他方法来完成它。

使用
set()

返回不包含重复项的集。如果出于某种原因,您需要返回列表:

woduplicates = list(set(lseperatedOrblist))

然而,这将有一个不同于您原始列表的顺序。

这实际上是因为您缺少一个大写字母

for i in mylist:
  if i not in newlist:
    newlist.append(i)
有目的地:

for i in lseparatedOrbList:   # capital 'L'
for j in lseparatedOrblist:   # lowercase 'l'
尽管更有效的方法是将内容插入
集合


如果维护列表顺序很重要(即,它必须是“稳定的”),

这应该可以为您做到:

new_list = list(set(old_list))

set
将自动删除重复项<代码>列表会将其转换回列表。

只需创建一个新列表进行填充,如果列表中的项目尚未在新列表中,请输入它,否则只需移动到原始列表中的下一个项目

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

您可以这样做:

x = list(set(x))
x = [1,2,3,4,5,6,7,8,9,10,2,1,6,31,20]
x = list(set(x))
x
示例:如果您这样做:

x = list(set(x))
x = [1,2,3,4,5,6,7,8,9,10,2,1,6,31,20]
x = list(set(x))
x
您将看到以下结果:

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

您只需考虑一件事:结果列表不会像原始列表那样排序(在过程中会丢失顺序)。

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

但是,代码还有其他问题。首先,您要遍历列表,因此
i
j
将是项而不是索引。此外,您不能在迭代集合时更改集合(当然,您“可以”在集合运行时更改集合,但疯狂就在于此,例如,您可能会跳过项)。还有一个复杂性问题,你的代码是O(n^2)。将列表转换为
集合
,然后再转换回
列表
(简单,但会将其余列表项洗牌),或者执行以下操作:

seen = set()
new_x = []
for x in xs:
    if x in seen:
        continue
    seen.add(x)
    new_xs.append(x)

这两种解决方案都要求项是可散列的。如果这是不可能的,您可能必须坚持您当前的方法,以消除上述问题。

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

seen = {}
new_list = [seen.setdefault(x, x) for x in my_list if x not in seen]
如果您不关心订单,您可以:

new_list = list(set(my_list))

寻找不易损坏的列表。它更快,因为它不会对已检查的条目进行迭代

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

维持秩序的现代方式是:

>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys(lseparatedOrbList))
正如Raymond Hettinger所讨论的。在Python3.5及更高版本中,这也是最快的方法-有关详细信息,请参阅链接答案。但是,密钥必须是可散列的(我认为您的列表就是这样)


从Python3.7开始,对dicts进行排序,因此上面的调用变为

>>> list(dict.fromkeys(lseparatedOrbList))
性能:

"""Dedup list."""
import sys
import timeit

repeat = 3
numbers = 1000

setup = """"""
def timer(statement, msg='', _setup=None):
    print(msg, min(
        timeit.Timer(statement, setup=_setup or setup).repeat(
            repeat, numbers)))

print(sys.version)
s = """import random; n=%d; li = [random.randint(0, 100) for _ in range(n)]"""
for siz, m in ((150, "\nFew duplicates"), (15000, "\nMany duplicates")):
    print(m)
    setup = s % siz
    timer('s = set(); [i for i in li if i not in s if not s.add(i)]', "s.add(i):")
    timer('list(dict.fromkeys(li))', "dict:")
    timer('list(set(li))', 'Not order preserving: list(set(li)):')
给出:

3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)]

Few duplicates
s.add(i): 0.008242200000040611
dict: 0.0037373999998635554
Not order preserving: list(set(li)): 0.0029409000001123786

Many duplicates
s.add(i): 0.2839437000000089
dict: 0.21970469999996567
Not order preserving: list(set(li)): 0.102068700000018

因此,尽管使用set.add对许多重复项进行列表理解,dict似乎始终更快-不确定进一步改变数字是否会产生不同的结果<代码>列表(集合)当然更快,但不会保留原始列表顺序,这里有一个要求

有一个更快的方法来解决这个问题:

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)

通过这种方式,您可以删除列表中多次出现的特定项:尝试删除所有5项

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


您需要维护列表的顺序吗?一个常见的问题:。您的错误是由于一个简单的输入错误:在第二个for循环中,您没有将lseparatedOrbList中的第二个“l”大写。很好,我想我没有忘记我所有的python,才两年。作为一个警告,我非常确定这是一个O(n^2)操作,因此您可能不想在大型列表(例如10000项)上使用它。如果你需要它来处理大列表,我会创建一个哈希表来检查(O(1),生成一个整体的O(n)实现),而不是检查列表,但是如果你处理的是大列表,我可能也不想使用python。正确的方法是使用set(),请看下面cilaris的回答。你说这不是正确的方法是什么意思?这就完成了要求的任务,没有创建集合的任何开销。创建集合会打乱顺序这会维护顺序,并且还能处理不可散列的列表项,这是一个优点。我刚刚对你的答案投了赞成票,但发现你建议理解列表。这种列表理解是行不通的,因为如果您这样使用它,它基本上会将
xs
列表重写为
ys
ys=[x代表x,如果x不在ys中]
。这是因为在理解中访问的
ys
是赋值前的
ys
。@Tadeck:该死,你说得对。好的提示。Smart and Pythonic:)如果原始列表
x
包含列表,则不起作用。值得注意的是,如果列表中有列表或集合,则此操作将失败。您还应明确注意,这不会保留元素顺序。这不会在所有情况下都起作用,如果原始列表
x
包含列表,则无法处理实例的dict列表。这是最好的答案,因为它同时考虑了保序和非保序。FWIW在我访问的系统上,当
s=set()时,50个随机整数的输入列表需要43µs;[i表示输入中的i,如果i不在s中,如果i不在s中。添加(i)]
取7和
列表(设置(inpu