简体   繁体   English

内部while循环没有被执行

[英]Inner while loop doesn't get executed

Found that the control never reaches the inner while loop in this snippet for deleting a duplicate number发现控件永远不会到达此代码段中的内部while循环以删除重复数字

numbers=[1,6,6,7]
k=len(numbers)
i=0
j=0
while i in range(k-1):
    while j in range(i+1,k):
        if numbers[i] == numbers[j]:
            numbers.remove(numbers[j])
            k-=1
            j-=1
        j += 1
    i += 1
print(numbers)

Your code does not make j start at i+1 .您的代码不会使ji+1开始。 Instead it starts at zero and never changes.相反,它从零开始,永远不会改变。 The inner loop never runs because 0 is outside of the range you are testing.内部循环永远不会运行,因为0超出了您正在测试的范围。

Try this simple change:试试这个简单的改变:

i=0
while i < k+1:
    j=i+1
    while j < k:
        if numbers[i] == numbers[j]:
            ...

The main change is moving the initialization of j inside the first while loop, so it updates each time you go through it, and never starts out less than or equal to i .主要变化是将j的初始化移动到第一个while循环中,因此每次您通过它 go 时它都会更新,并且从不小于或等于i开始。

The other change I made is much less important.我所做的另一项更改不那么重要。 Rather than using i in range(...) and j in range(...) for the while loop conditions, I just did an inequality test.而不是使用i in range(...)j in range(...)作为while循环条件,我只是做了一个不等式测试。 This is exactly the same as what the range membership test does under the covers, but avoids unnecessary testing for things that can't happen (like j being too small, now).这与range成员测试在幕后所做的完全相同,但避免了对不可能发生的事情进行不必要的测试(比如现在j太小了)。 It also makes the loop look a lot less like a for loop, which uses for i in range(...) syntax a lot (with a different meaning).它还使循环看起来不像for循环,它大量使用for i in range(...)语法(具有不同的含义)。

Another issue you may run into later, with some sets with multiple sets of duplicates is that your code to remove the j th element probably doesn't do what you intend.稍后您可能会遇到的另一个问题是,有些集合具有多组重复项,即您删除第j个元素的代码可能没有达到您的预期。 The call numbers.remove(numbers[j]) removes the first value equal to numbers[j] from the list, which is going to be the one at index i rather than the one at index j .调用numbers.remove(numbers[j])从列表中删除等于numbers[j]第一个值,这将是索引i处的值,而不是索引j处的值。 To delete a list item by index, you want to use del numbers[j] .要按索引删除列表项,您需要使用del numbers[j]

You could remove duplicates from a list in Python by using the dict.fromkeys() .您可以使用dict.fromkeys()从 Python 中的列表中删除重复项。

numbers=[1,6,6,7]
final_numbers = list(dict.fromkeys(numbers))
print(final_numbers)

In this example, we use the dict.fromkeys() method to create a dictionary from numbers variable.在此示例中,我们使用dict.fromkeys()方法从numbers变量创建字典。 We then use list() to convert our data from a dictionary back to a list.然后我们使用list()将我们的数据从字典转换回列表。 Then, on the final line, we print out our revised list.然后,在最后一行,我们打印出修改后的列表。

Another option is to use set .另一种选择是使用set Sets are used to store collections of unique items in Python. Sets用于存储 Python 中唯一项目的 collections。 Unlike lists , sets cannot store duplicate values.lists不同, sets不能存储重复值。 We can convert our list to a set to remove duplicated items.我们可以将我们的列表转换为一个集合以删除重复的项目。

numbers=[1,6,6,7]
final_numbers = list(set(numbers))
print(final_numbers)

It doesn't reach because j and i starts at 0 value and in the inner while loop the condition is j in range(i+1, k) which means range(1, 4) and 0 in range(1, 4) would be False .它没有达到,因为ji从 0 值开始,并且在内部 while 循环中,条件是j in range(i+1, k)这意味着range(1, 4)0 in range(1, 4)会是False的。 Anyways, you should avoid using j and i as counters and use a for loop instead.无论如何,您应该避免使用ji作为计数器,而是使用for循环。

But the solution is easier and doesn't need to traverse the list, if you wanna remove the duplicate values, you can do as below:但解决方案更简单,不需要遍历列表,如果要删除重复值,可以执行以下操作:

numbers = [1, 6, 6, 7]
print(list(set(numbers)))

The result is: [1, 6, 7]结果是: [1, 6, 7]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM