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?

Answers


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[0]  # results in num = [2, 3, 4]
del num [1]  # 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[0]
>>> a
[2, 3, 4, 5]
>>> del a[1]
>>> a
[2, 4, 5]
>>> del a[2]
>>> a
[2, 4]
>>> del a[3]
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.

http://gsb-eng.com/why-python-list-mutation-is-not-a-good-idea/


Need Your Help

Rake db:migrate mysql error

mysql ruby-on-rails ruby-on-rails-3 rake

I am new to ROR. I was just following the tutorials at tutorials point. I have installed following gems:

Sort optimization in MIPS assembly language

arrays sorting optimization assembly mips

I have a code which sorts an array, implemented with MIPS assembly language. I want to know if any further optimization is possible.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.