Python: List indexing for loop deletion glitch
This is a very tricky problem to explain. I was playing around with Python's list methods, particularly the del index object. I wanted to create a simple script that would create a list of integers from 1 to 100, and then a for loop which would delete the odd numbers from the list.
Here is the script I wrote:
def main(): num = list(range(1,101)) print(num) for i in range(0,101): del num[i] print(num) main()
Seems like it would work right? I thought so too, until I ran it.
I am not sure why, but when i was passed to the del num[i] index, the number itself doubled.
When I ran it, I received IndexError: list assignment index out of range.
When I changed the parameters from range(0,101) to range(0,10), I discovered that it deleted all the odd numbers from 1 to 20.
In other words, i in the index is doubling when it shouldn't. Can I get some information about this?
When you use the del keyword inside of your for loop, it's completely removing the item from the original num list you made. By doing so, the length of your list is getting smaller and smaller with each iteration through the loop.
This also explains why it's only removing the odd numbers, since the indexes are shifting down after each delete, allowing the even numbers to slip through the cracks of your program:
num = range(1, 5) # num = [1, 2, 3, 4] del num # results in num = [2, 3, 4] del num  # deletes 3, and num now = [2, 4] etc. for a longer loop
To delete the odd numbers, consider using a conditional to check the %2 == 0 status and the list.remove() method:
num = range(1, 101) for i in num: if i % 2 != 0: num.remove(i) print(num)
Or a list comprehension inside your main() function:
return [x for x in num if x % 2 == 0]
The size of the list is reduced when you delete items. After about 50 loop iterations, you have about 50 items in the list, so the nest iteration tries to delete something outside the list.
Here's a simulated run:
>>> a = [1, 2, 3, 4, 5] >>> a [1, 2, 3, 4, 5] >>> del a >>> a [2, 3, 4, 5] >>> del a >>> a [2, 4, 5] >>> del a >>> a [2, 4] >>> del a Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list assignment index out of range
Your iterate through the range from 0 to 101, and delete one item from num on each iteration, so the length of the num is reducing and you finally get an IndexError.
This problem is verymuch similar to mutating a list while iterating over the same list, go through below link which helps you to understand this situation better.