In Python's list loop traversal, the correct method for deleting data is pythonlist.
When I was a beginner in Python, I encountered such a problem. When traversing the list, I deleted the Qualified Data, but always reported an exception. The Code is as follows:
num_list = [1, 2, 3, 4, 5]print(num_list)for i in range(len(num_list)): if num_list[i] == 2: num_list.pop(i) else: print(num_list[i])print(num_list)
Exception: IndexError: list index out of range
The reason is that after the elements in the list are deleted, the actual length of the list is reduced, but the number of cycles is not reduced, and the traversal is still performed according to the length of the original list, which causes index overflow.
So I modified the Code as follows:
num_list = [1, 2, 3, 4, 5]print(num_list)for i in range(len(num_list)): if i >= len(num_list): break if num_list[i] == 2: num_list.pop(i) else: print(num_list[i])print(num_list)
No exception is reported, but the output is as follows:
[1, 2, 3, 4, 5]145[1, 3, 4, 5]
[Finished in 0.441s]
Although the element [2] in the list is indeed deleted, the print result in the loop is incorrect, and it is missing [3].
After thinking about the cause, when the condition is met, after the element [2] is deleted, all the following elements are moved forward, so [3, 4, 5] moves forward, then the index of the element [3] is changed to the index of the previous [2] (now the index of [3] is changed to 1), and the subsequent elements are like this. However, the next for loop starts with subscript index 2. Therefore, when element [4] is taken out, [3] is omitted.
The code is modified as follows, and the result is the same, but it is not changed at all:
num_list = [1, 2, 3, 4, 5]print(num_list)for item in num_list: if item == 2: num_list.remove(item) else: print(item)print(num_list)
Now that I know the root cause of the problem and want to find the correct method, it is not difficult, so I wrote the following code:
num_list = [1, 2, 3, 4, 5]print(num_list)i = 0while i < len(num_list): if num_list[i] == 2: num_list.pop(i) i -= 1 else: print(num_list[i]) i += 1print(num_list)
The execution result is completely correct:
[1, 2, 3, 4, 5]1345[1, 3, 4, 5]
[Finished in 0.536s]
My practice is that since we can't use the for loop, we can use the while loop to solve the problem. During each while loop, the length of the list is checked (I <len (num_list). In this way, the index overflow is avoided, after the element [2] is deleted, manually index the current subscript-1 so that during the next loop, the element obtained through the subscript index after-1 is [3], instead of skipping [3].
Of course, this is not the optimal solution, so I found a general solution: 1. Reverse loop traversal; 2. traversing the copy list and operating on the original list.
1. Inverted loop:
num_list = [1, 2, 3, 4, 5]print(num_list)for i in range(len(num_list)-1, -1, -1): if num_list[i] == 2: num_list.pop(i) else: print(num_list[i])print(num_list)
The execution result is completely correct. So why is there a problem when deleting a forward-order loop and deleting a reverse-order loop OK? Amount ...... It's hard to express your speech. Let's draw an ugly picture.
1) delete a positive loop:
After the element [2] is deleted, the subscript index of the next cycle is 2, but in this case, [4] is stored, so [3] is missing.
2) Delete in reverse order
After the element [2] is deleted, [3, 4, 5] is pushed forward, but it does not matter because the subscript index of the next loop is 0, which stores [1], so it is exactly the expected correct element value.
2. traverse the copied list and operate the original list.
num_list = [1, 2, 3, 4, 5]print(num_list)for item in num_list[:]: if item == 2: num_list.remove(item)
else: print(item)print(num_list)
The original list is num_list. In fact, num_list [:] is a copy of the original num_list and a new list. Therefore, we traverse the new list, deleting the elements in the original list will not cause index overflow, and finally get the desired final result. The disadvantage of this method may be that for a large list, copying may occupy a lot of memory. In this case, we can use the reverse Traversal method.