-1
d = 3
cl = [1,3,4]

for i in cl:
    if i <= d:
        cl.remove(i)
print(cl)

output >> [3,4]

The number 3 should not be in the list as it passed the i <= d condition so cl.remove should've been called but it is in the output. What am I doing wrong here?

Woody1193
  • 7,252
  • 5
  • 40
  • 90
Rahul
  • 337
  • 2
  • 14
  • Don't iterate over the list that you are removing from – rdas Jul 07 '20 at 05:29
  • your list got updated in the loop while reference to iterator isn't it remain next(next(c)) – sahasrara62 Jul 07 '20 at 05:29
  • 1
    Does this answer your question? [How to remove items from a list while iterating?](https://stackoverflow.com/questions/1207406/how-to-remove-items-from-a-list-while-iterating) – Nick Jul 07 '20 at 05:49

4 Answers4

2

It happens because you're removing elements from list while iterating over it. It could be solved like this

[num for num in cl if num > d]
0

This works

d = 3
cl = [1, 3, 4]
for i in range(len(cl)):
    if cl[i-1] <= d:
        cl.remove(cl[i-1])
print(cl)

Please can you accept if it works...

0

This is the result of mutating a data structure during iteration. The for loop essentially creates an iterator over your list, with each item calling next(iterator). However, popping items off changes what the iterator is looking at

a = [1, 2, 3, 4]

it = iter(a)

# First iteration
next(it)
1

# remove element
a.pop(0)
1

# we skipped 2!
next(it)
3

Why? Well, we effectively changed what element the iterator is pointing to by removing the element we were currently on. We were looking at the first element in the sequence, but that was removed, so now the second element is the first one. So the call to next then points to the following element. This winds up looking like it was skipped when it wasn't, you just unintentionally had elements shuffled forward.

To avoid this, it's best to create a new list by filtering, as @AlexanderLekontsev suggests in his answer. This avoids mutating while iterating. You can do this with a standard loop with append like so:

newlist = []

for num in cl:
    if num >= d:
        newlist.append(num)
C.Nivs
  • 12,353
  • 2
  • 19
  • 44
0

Essentially, because you are removing elements from the list while iterating over it, you have skipped over the value 3.

In the first iteration of your for-loop, you remove the value 1. Because of how iterations work in Python, in your second iteration of the for-loop, you are looking for next(next(cl)). But, cl has been updated to [3,4], since you removed 1. So now next(next(cl)) = next(3) = 4 and so you've skipped over 3.

You can resolve this by creating a new list and updating it as you go along. An easy way to do this using list comprehension is simply [num for num in cl if num > d].

tanyhb1
  • 1
  • 2