我如何使用python检查列表并删除所有重复项?我不想指定重复的项目是什么 - 我希望代码确定是否存在并删除它们,如果是这样,只保留每个项目的一个实例.如果列表中有多个重复项,它也必须工作.
例如,在我的下面的代码中,列表lseparatedOrbList有12个项目 - 一个重复六次,一个重复五次,并且只有一个实例.我希望它改变列表,因此只有三个项目 - 每个项目中的一项,并且它们之前出现的顺序相同.我试过这个:
for i in lseparatedOrbList:
for j in lseparatedOrblist:
if lseparatedOrbList[i] == lseparatedOrbList[j]:
lseparatedOrbList.remove(lseparatedOrbList[j])
Run Code Online (Sandbox Code Playgroud)
但我得到错误:
Traceback (most recent call last):
File "qchemOutputSearch.py", line 123, in <module>
for j in lseparatedOrblist:
NameError: name 'lseparatedOrblist' is not defined
Run Code Online (Sandbox Code Playgroud)
我猜是因为这是因为我试图循环通过lseparatedOrbList而我循环通过它,但我想不出另一种方法来做到这一点.
Jac*_*cob 82
用途set():
woduplicates = set(lseparatedOrblist)
Run Code Online (Sandbox Code Playgroud)
返回没有重复项的集合.如果您出于某种原因需要列表:
woduplicates = list(set(lseperatedOrblist))
Run Code Online (Sandbox Code Playgroud)
Jon*_*nde 77
只需填写一个新列表,如果列表中的项目尚未在新列表中输入,则只需转到原始列表中的下一个项目即可.
for i in mylist:
if i not in newlist:
newlist.append(i)
Run Code Online (Sandbox Code Playgroud)
我认为这是正确的语法,但我的python有点不稳定,我希望你至少得到这个想法.
Tad*_*eck 29
你可以这样做:
x = list(set(x))
Run Code Online (Sandbox Code Playgroud)
示例:如果您执行类似的操作:
x = [1,2,3,4,5,6,7,8,9,10,2,1,6,31,20]
x = list(set(x))
x
Run Code Online (Sandbox Code Playgroud)
你会看到以下结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 31]
Run Code Online (Sandbox Code Playgroud)
您应该只考虑一件事:结果列表不会作为原始列表排序(在此过程中将丢失订单).
Pao*_*tti 20
这应该更快,并将保留原始顺序:
seen = {}
new_list = [seen.setdefault(x, x) for x in my_list if x not in seen]
Run Code Online (Sandbox Code Playgroud)
如果您不关心订单,您可以:
new_list = list(set(my_list))
Run Code Online (Sandbox Code Playgroud)
Mr_*_*s_D 11
保持秩序的现代方法是:
>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys(lseparatedOrbList))
Run Code Online (Sandbox Code Playgroud)
正如 Raymond Hettinger在这个答案中所讨论的那样。在 python 3.5 及更高版本中,这也是最快的方法 - 有关详细信息,请参阅链接的答案。但是,键必须是可散列的(我认为在您的列表中就是这种情况)
从 python 3.7 开始,有序字典是一个语言特性,所以上面的调用变成
>>> list(dict.fromkeys(lseparatedOrbList))
Run Code Online (Sandbox Code Playgroud)
表现:
"""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)):')
Run Code Online (Sandbox Code Playgroud)
给出:
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
Run Code Online (Sandbox Code Playgroud)
因此 dict 似乎始终更快,尽管使用 set.add 对许多重复项进行列表理解 - 不确定进一步改变数字是否会产生不同的结果。list(set)当然更快,但不保留原始列表顺序,这是这里的要求
小智 7
不,这只是一个错字,最后的"清单"必须大写.您可以将循环嵌套在同一个变量上(尽管很少有理由).
但是,代码还有其他问题.对于初学者来说,你是在迭代列表,所以i并且j将是项目而不是索引.此外,你不能在迭代它时改变一个集合(好吧,你可以"运行",但疯狂就是这样 - 例如,你可以跳过项目).然后是复杂性问题,你的代码是O(n ^ 2).要么将列表转换set为a list又将其转换为(简单,但将剩余的列表项随机播放)或执行以下操作:
seen = set()
new_x = []
for x in xs:
if x in seen:
continue
seen.add(x)
new_xs.append(x)
Run Code Online (Sandbox Code Playgroud)
两种解决方案都要求物品可以清洗.如果那是不可能的,你可能不得不坚持你目前的方法没有提到的问题.
这应该为你做:
new_list = list(set(old_list))
Run Code Online (Sandbox Code Playgroud)
set将自动删除重复项.list将它扔回列表.
实际上,这是因为您缺少一个大写字母。
故意凹陷:
for i in lseparatedOrbList: # capital 'L'
for j in lseparatedOrblist: # lowercase 'l'
Run Code Online (Sandbox Code Playgroud)
虽然更有效的方法是将内容插入到set.
如果维护列表顺序很重要(即它必须是“稳定的”),请查看此问题的答案
| 归档时间: |
|
| 查看次数: |
154764 次 |
| 最近记录: |