我试图删除列表中所有重复的数字。
我试图了解我的代码出了什么问题。
numbers = [1, 1, 1, 1, 6, 5, 5, 2, 3]
for x in numbers:
if numbers.count(x) >= 2:
numbers.remove(x)
print(numbers)
我得到的结果是:
[1, 1, 6, 5, 2, 3]
答案 0 :(得分:2)
numbers = [1, 1, 1, 1, 6, 5, 5, 2, 3]
使用列表中的shallow copy
:
for x in numbers[:]:
if numbers.count(x) >= 2:
numbers.remove(x)
print(numbers) # [1, 6, 5, 2, 3]
替代:
保留列表的顺序:
print(list(dict.fromkeys(numbers).keys())) # [1, 6, 5, 2, 3]
使用more_itertools.unique_everseen(iterable, key=None)
:
from more_itertools import unique_everseen
print(list(unique_everseen(numbers))) # [1, 6, 5, 2, 3]
import pandas as pd
print(pd.unique(numbers).tolist()) # [1, 6, 5, 2, 3]
使用collections.OrderedDict([items])
:
from collections import OrderedDict
print(list(OrderedDict.fromkeys(numbers))) # [1, 6, 5, 2, 3]
使用itertools.groupby(iterable[, key])
:
from itertools import groupby
print([k for k,_ in groupby(numbers)]) # [1, 6, 5, 2, 3]
忽略列表的顺序:
使用numpy.unique
:
import numpy as np
print(np.unique(numbers).tolist()) # [1, 2, 3, 5, 6]
使用set()
:
print(list(set(numbers))) # [1, 2, 3, 5, 6]
print(list(frozenset(numbers))) # [1, 2, 3, 5, 6]
答案 1 :(得分:2)
我想这是在不使用库函数的情况下自己编写代码的想法。然后,我仍然建议使用其他集合结构来存储您以前的项目,并且只对数组进行一次操作:
numbers = [1, 1, 1, 1, 6, 5, 5, 2, 3]
unique = set()
for x in numbers:
if x not in unique:
unique.add(x)
numbers = list(unique)
print(numbers)
如果要使用代码,则问题在于您需要为每个循环修改in,这在大多数编程语言中都是很大的缺点。尽管Python允许您执行此操作,但此答案中已经描述了问题和解决方案:How to remove items from a list while iterating?:
注:循环修改序列时有一个微妙之处(这仅适用于可变序列,即列表)。内部计数器用于跟踪下一个要使用的项目,并且在每次迭代时都会递增。当该计数器达到序列的长度时,循环终止。这意味着,如果套件从序列中删除当前(或上一个)项目,则下一个项目将被跳过(因为它获取已被处理的当前项目的索引)。同样,如果套件在当前项目之前按顺序插入一个项目,则下次通过循环再次处理当前项目。这会导致令人讨厌的错误,可以通过使用整个序列的一部分(例如,
for x in a[:]: if x < 0: a.remove(x)
答案 2 :(得分:1)
为什么不简单地使用一套:
numbers = [1, 1, 1, 1, 6, 5, 5, 2, 3]
numbers = list(set(numbers))
print(numbers)
答案 3 :(得分:1)
在进行任何操作之前,我能提供的第一个建议是不要对正在循环的数组进行编辑。各种古怪的事情都会发生。您的代码很好(尽管我建议您阅读其他答案,但是有一种更简单的方法可以使用set
来做到这一点,for loop syntax
可以为您处理重复的事情)。
与其从正在循环的数组中删除数字,不如通过切片将您正在循环的数组克隆到实际的numbers = [1, 1, 1, 1, 6, 5, 5, 2, 3]
for x in numbers[:]:
if numbers.count(x) >= 2:
numbers.remove(x)
print(numbers)
print("Final")
print(numbers)
中。
numbers[:]
答案是[1, 1, 1, 6, 5, 5, 2, 3]
[1, 1, 6, 5, 5, 2, 3]
[1, 6, 5, 5, 2, 3]
[1, 6, 5, 5, 2, 3]
[1, 6, 5, 5, 2, 3]
[1, 6, 5, 2, 3]
[1, 6, 5, 2, 3]
[1, 6, 5, 2, 3]
[1, 6, 5, 2, 3]
Final
[1, 6, 5, 2, 3]
,它会返回数组的副本。这是打印输出:
numbers = [1, 1, 1, 1, 6, 5, 5, 2, 3]
nubmers_a_set = {x for x in numbers }
print(nubmers_a_set)
在这里留下一个占位符,直到我弄清楚如何解释在您的特定情况下为什么它不起作用,例如逐步的实际原因。
使用美丽的Python语言解决此问题的另一种方法是通过列表理解和设置。
为什么要设置。因为此数据结构的定义是元素唯一,所以即使您尝试放入多个相同的元素,它们也不会在集合中重复出现。酷吧?
List comprehension是用于在一行中循环的一些语法糖,可以在Python中习惯使用它,或者经常使用它,或者经常使用它:)
因此,通过列表理解,您将迭代一个可迭代对象并返回该项目。在下面的代码中, x 代表数字中的每个数字, x 返回为 set 集的一部分。因为集合处理重复项...瞧,所以代码就完成了。
{{1}}
答案 4 :(得分:0)
这似乎是家庭作业,但这是可能的解决方法:
$1
此解决方案不保留顺序。如果还需要订购,请使用:
import numpy as np
numbers = [1, 1, 1, 1, 6, 5, 5, 2, 3]
filtered = list(np.unique(numbers))
print(filtered)
#[1, 2, 3, 5, 6]
答案 5 :(得分:0)
您为什么不使用fromkeys
?
numbers = [1, 1, 1, 1, 6, 5, 5, 2, 3]
numbers = list(dict.fromkeys(numbers))
输出:[1,6,5,2,3]
答案 6 :(得分:0)
流程如下。
现在列表为[1、1、1、1、6、5、5、2、3],索引为0。
x
为1。numbers.count(1)
为4,因此删除了索引0处的1。
现在numbers
列表变为[1、1、1、6、5、5、2、3],但索引将+1并变为1。
x
为1。numbers.count(1)
为3,因此删除了1和索引1。
现在numbers
列表变为[1、1、6、5、5、2、3],但索引将+1并变为2。
x
将为6。
等...
这就是为什么有两个1的原因。
如果我错了,请纠正我。谢谢!
答案 7 :(得分:0)
一种奇特的方法是使用collections.Counter
:
>>> from collections import Counter
>>> numbers = [1, 1, 1, 1, 6, 5, 5, 2, 3]
>>> c = Counter(numbers)
>>> list(c.keys())
[1, 6, 5, 2, 3]
此方法具有线性时间复杂度(O(n)
),并使用了性能卓越的库。
答案 8 :(得分:0)
您可以尝试:
from more_itertools import unique_everseen
items = [1, 1, 1, 1, 6, 5, 5, 2, 3]
list(unique_everseen(items))
或
from collections import OrderedDict
>>> items = [1, 1, 1, 1, 6, 5, 5, 2, 3]
>>> list(OrderedDict.fromkeys(items))
[1, 2, 0, 3]
更多,您可以在这里找到 How do you remove duplicates from a list whilst preserving order?