为什么在使用此代码时我会更改列表?

时间:2018-04-21 08:11:40

标签: python

我想使用这种结构来减少列表中的重复元素,但是当我使用此代码时,列表保持不变。有人可以帮我吗?

例如,项= [1,2,3,4,5,6,7,8,9,1,2,6,7]

def duplicated(item):
        i=0
        j=0
        while i<len(item):
                while j<len(item):
                        if item[j]==item[i] and i!=j:
                                del item[j]
                        j+=1
                i+=1
        return item

4 个答案:

答案 0 :(得分:2)

为了解决您的代码无法正常工作的原因,这是因为您在函数的开头初始化j,因此在i循环的第一次迭代之后,它是len(item)-1,然后永远不会为将来的循环重置。

这意味着您错过了许多重复项。

因为我们需要在每个循环中初始化它,我们仍然需要知道该怎么做。如果我们将其初始化为0,那么我们将检查列表中当前j值后面的重复项,这样就浪费了时间。为了提高效率,我们应该将其初始化为i+1,以便我们在 i之后检查数字是否有重复项,因为我们已经知道{{1}处的值没有重复在列表中的索引i之前。这也简化了i,因为我们不再需要检查if

最后一件事是,当您使用i != j删除j时,之后的所有索引现在都会向下移动一个。所以我们还需要从del中减去1,这样我们现在可以在刚刚删除的元素之后直接检查元素,它现在与我们刚刚删除的元素相同(因为它们向下移动) )。

所以,在代码中:

j

它适用于人们给出的例子:

def duplicated(item):
        i = 0
        while i < len(item):
                j = i + 1
                while j < len(item):
                        if item[j] == item[i]:
                                del item[j]
                                j -= 1
                        j += 1
                i += 1
        return item

但是,这个解决方案是复杂性>>> duplicated([1,2,3,4,5,6,7,8,9,1,2,6,7]) [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> duplicated([1,2,3,4,5,6,7,8,9,1,1,2,6,7]) [1, 2, 3, 4, 5, 6, 7, 8, 9] 的当前,因为我们使用嵌套循环所以所花费的时间与输入列表的平方大小成正比。

但是如果我们能够将算法修改为仅使用一个循环,我们会将复杂度降低到O(n^2)。这可以通过使用set进行查找来完成。添加和检查元素是否在集合中是O(n)(平均大小写),因此我们可以使用它们来加快速度。

因此,如果我们有一个包含我们已经看过的元素的集合,那么对于每个future元素,如果它已经在O(1)集合中,我们将其删除,否则我们将其添加到此集合。 / p>

所以,在代码中:

seen

我可以确认这也通过了上面的测试用例。

我应该指出的最后一件事是,在这里删除元素时,我没有从指针中减去,这是因为在我们知道之前我们减去之前它会增加并且我们希望它是相同的,但是在这里,它仅在def duplicated(item): seen = set() i = 0 while i < len(item): if item[i] in seen: del item[i] else: seen.add(item[i]) i += 1 return item 块中递增,因此如果我们不做任何事情,它将保持不变。

答案 1 :(得分:0)

实际上变量j应该从i选择的下一项开始。

def duplicated(item):
    i=0
    while i<len(item):
        j = i+1
        while j<len(item):
            if item[j]==item[i] and i!=j:
                del item[j]
                j -= 1
            j+=1
        i+=1
    return item

答案 2 :(得分:-1)

您应该在j循环内的每个回合重新初始化i var,否则,j在第一次迭代后总是等于len(item)

def duplicated(item):
    i=0
    while i<len(item):
        j=0
        while j<len(item):
            if item[j]==item[i] and i!=j:
                print(i,j )
                del item[j]
            j+=1
        i+=1
    return item

然而,最好的方法,如果你不关心你的列表顺序,做你想要的可能是将你的列表转换为一个集然后回到列表,有一个集只能有不同的元素

def duplicated(item):
    return list(set(item))

答案 3 :(得分:-1)

您需要在每次嵌套while循环开始时重新启动j:

def duplicated(item):
        i=0
        j=0
        while i<len(item)-1:
            j=i+1
            while j<len(item):
                    if item[j]==item[i]:
                            del item[j]
                            j -= 1
                    j+=1
            i+=1
        return item

OUT

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

但是你可以尝试下面更简单的代码,它仍然是列表的插入顺序

def duplicated(item):
    unique_list=[]
    for i in item:
        if i not in unique_list:
            unique_list.append(i)
    return unique_list