Python 通过编辑列表从列表中删除重复条目

Python 通过编辑列表从列表中删除重复条目,python,list,duplicates,Python,List,Duplicates,有一个列表arr=[1,3,4,5,2,3,4,2,5,7,3,8,1,9,6,2,1,2,1,3,4,4,6,9] 要删除重复的值,以便原始列表应包含所有元素的单个实例。不希望创建额外列表并附加列表中的元素。也不希望使用内置的“set” 尝试使用以下代码执行此操作: l = len(arr) for x in range(l): for y in range(x+1,l): if arr[x] == arr[y]: del arr[y] 尝试

有一个列表
arr=[1,3,4,5,2,3,4,2,5,7,3,8,1,9,6,2,1,2,1,3,4,4,6,9]
要删除重复的值,以便原始列表应包含所有元素的单个实例。不希望创建额外列表并附加列表中的元素。也不希望使用内置的“set”

尝试使用以下代码执行此操作:

l = len(arr)
for x in range(l):
    for y in range(x+1,l):
         if arr[x] == arr[y]:
            del arr[y]
尝试了上面的代码及其抛出错误

"IndexError: list index out of range"
我所理解的是,当删除值时,列表的大小会发生变化,从而引发错误。因此,我做了以下更改。但它仍然以同样的错误失败:

l = len(arr)
for x in range(l):
    for y in range(x+1,l):
         if arr[x] == arr[y]:
            t = y
            del arr[y]
            y = t - 1
有人能帮我吗?
提前感谢。

您正试图通过在局部变量
l
中缓存列表的长度来提高代码的效率。但是,这并没有帮助,因为列表在循环中被修剪,并且您没有保持缓存长度变量的同步

for index in range(len(arr)-1,0,-1): 
    if arr[index] in arr[:index]:
        del arr[index]
通过向后遍历数组并查找每个元素的早期出现,可以避免担心列表的长度一直在变化

此方法还保留元素在原始数组中出现的顺序。注:本说明仅删除重复项(也称为后续事件)


例如,列表
[9,3,4,3,5]
应该减少到
[9,3,4,5]
,因为第二次出现的
3
被视为重复,应该删除。

这种方法如何:

>>> set(arr)
set([1, 2, 3, 4, 5, 6, 7, 8, 9]) #Just to compare it with the results below.
>>> arr = [1,3,4,5,2,3,4,2,5,7,3,8,1,9,6,2,1,2,1,3,4,3,4,6,9]
>>> arr.sort()
>>> arr
[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 9]
>>> for i in arr:
    while arr.count(i) > 1:
        del arr[i]


>>> arr
[1, 2, 3, 4, 5, 6, 7, 8, 9]
另一种方法是在对列表进行排序后,查找每个数字要删除的子列表的长度:

>>> arr = [1,3,4,5,2,3,4,2,5,7,3,8,1,9,6,2,1,2,1,3,4,3,4,6,9]
>>> arr.sort()
>>> arr
[1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6, 7, 8, 9, 9]
>>> for i,j in enumerate(arr):
        del arr[i+1:i+arr.count(j)]
>>> arr
[1, 2, 3, 4, 5, 6, 7, 8, 9]

由于范围的限制,这些行不会有丝毫的区别。不管怎样,现在你明白了为什么涉及
set()
或创建第二个
列表的策略很流行。你不想使用set有什么特殊原因吗?毫无疑问:P@danidee::不想使用set或第二次创建列表没有特殊原因。只想检查一下是否有其他方法可以做到这一点。
arr[:]=[ele for i,ele in enumerate(arr)如果ele不在arr[:i]]
将是一种更好的使用方法enumerate@PadraicCunninghan .. 你说的是可读的还是高效的?效率高一点,但我不会真的认为这是解决问题的有效方法,它也会保持元素遇到的顺序。但所有这些都涉及到对原始列表进行排序,从而破坏了元素的原始序列。这是OP没有要求的副作用。排序操作本身在计算上也很昂贵(如果输入列表仅包含数字,则即使是
set
构造函数也会执行排序)。如果效率很重要(谁知道这些列表会有多大?),那么对原始列表进行就地编辑是一条可行之路,并且只需做最少的工作。