-2

I want to delete all the elemnts of the list from the index 4 to 9. Why isn't the code below working.

m=[0,1,2,3,4,5,6,7,8,9]
for i in range(4,10,1):
    del m[i]

The output is:

Traceback (most recent call last):
  File "<pyshell#45>", line 2, in <module>
    del m[i]
IndexError: list assignment index out of range

But after this the contents of m becomes `[0, 1, 2, 3, 5, 7, 9]

Knight_bot
  • 29
  • 5
  • If you del element 4, all the higher elements shift down to fill in the gap. So the next index you delete is off by one. Each time you delete another element, you're increasing the offset and deleting the wrong elements. – khelwood Oct 27 '17 at 12:32
  • Possible duplicate of [How to remove list elements in a for loop in Python?](https://stackoverflow.com/questions/10665591/how-to-remove-list-elements-in-a-for-loop-in-python) – Maurice Meyer Oct 27 '17 at 12:32

5 Answers5

2

The list size is shrinking as you're deleting the elements. Take this for example:

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

for i in range(4,10,1):
    print(i)
    del m[i]
    print(m)

Output

Traceback (most recent call last):
 line 5, in <module>
    del m[i]
IndexError: list assignment index out of range
4
[0, 1, 2, 3, 5, 6, 7, 8, 9]
5
[0, 1, 2, 3, 5, 7, 8, 9]
6
[0, 1, 2, 3, 5, 7, 9]
7

Process finished with exit code 1

You can see the script fails when the index to delete is 7, but the index range of the list is 0-6, hence the index being out of range.

Chris
  • 15,819
  • 3
  • 24
  • 37
1

One problem is that the del m[i] happen sequentially, not all at the same time. And while the value of i increases, the size of m decreases, so the original elements have been shifted to the left, no longer in their original positions.

And in any case, a better way to delete a range of elements is using slices, for example:

m[start:end] = []

This deletes the elements with indexes start .. end - 1.

To use a step in the range, then you can use del with a slice with a step:

del m[start:end:step]
janos
  • 120,954
  • 29
  • 226
  • 236
0

For every element in your loop that you remove, the indexes and the length of the list changes. so at a certain point, you are accesing an index that is higher than the length of the list.

Just use list slicing for that:

# If you want the first 4 elements
m=[0,1,2,3,4,5,6,7,8,9]
print(m[:4]) # prints [0,1,2,3]

# Or if you want to go slicing from reverse:
m=[0,1,2,3,4,5,6,7,8,9]
print(m[:-6]) # prints [0,1,2,3]
Igl3
  • 4,900
  • 5
  • 35
  • 69
0

You are deleting from a sequence upon which you are iterating; as you remove items, the position of the rest changes.

You can do this in reverse order, starting from the highest index, but you must be careful at the boundaries of the range:

m = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
for i in range(9, 3, -1): 
    m.pop(i)

m

Or you can do this by constructing a new list that keeps the items you need:

m = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 
res = []
for idx, elt in enumerate(m):
    if idx not in range(4, 10):
        res.append(elt)
m = res

m

In both cases, the output is:

[0, 1, 2, 3]
Reblochon Masque
  • 35,405
  • 10
  • 55
  • 80
0

You can use remove method :

m=[0,1,2,3,4,5,6,7,8,9]
for i in range(4,10,1):
    m.remove(i)

print(m)

[0, 1, 2, 3]
Aaditya Ura
  • 12,007
  • 7
  • 50
  • 88