0
a = [2, 3, 4, 5, 10, 12, 13, 17, 1234, 4321, 12345, 13579]
b = a
for i in b:
    a.remove(i)
print(a)

The output is [3, 5, 12, 17, 4321, 13579] instead of the expected empty list, why is that so?

Actually I wanted to write a program to remove all integers in a list with at least one even single digit, i.e.

a = [2, 3, 4, 5, 10, 12, 13, 17, 1234, 4321, 12345, 13579]
b = a
for i in b:
    if str(j) == 0 or str(j) == 2 or str(j) == 4 or str(j) == 6 or str(j) == 8:
        a.remove(i)
print(a)

But that doesn't work in the way expected. How should I debug that?

U13-Forward
  • 69,221
  • 14
  • 89
  • 114
Sato
  • 1,013
  • 1
  • 12
  • 27

3 Answers3

1

The problem is that each time you remove an element, you make the list shorter, but keep your position from the loop constant. Essentially you skip over every other element when removing in a loop like this. Consider the example a = [1,2,3]. On the first iteration, you remove 1. So a becomes [2,3] and you move your position to the second element, which is now 3, so you've skipped 2.

How you can fix it is by filtering with a list comprehension. Here's an example:

a = [2, 3, 4, 5, 10, 12, 13, 17, 1234, 4321, 12345, 13579]
filtered = [x for x in a if not any(digit in str(x) for digit in '02468')]
Henry Woody
  • 14,024
  • 7
  • 39
  • 56
0

Iterating trough list than removing element is not a good thing:

so

a = [2, 3, 4, 5, 10, 12, 13, 17, 1234, 4321, 12345, 13579]
b = a
for i in b:
    a.remove(i)
print(a)

And also BTW b is same as a, now because you should do:

b=a[:]

or:

b=a.copy()

To solve it either do:

a = [2, 3, 4, 5, 10, 12, 13, 17, 1234, 4321, 12345, 13579]
b = a[:]
for i in b[:]:
    a.remove(i)
print(a)

OR:

a = [2, 3, 4, 5, 10, 12, 13, 17, 1234, 4321, 12345, 13579]
b = a[:]
while len(a):
    a.pop()
print(a)

See: How to clone or copy a list?

And: How to remove list elements in a for loop in Python?

Also to answer do:

print([i for i in a any(i.__contains__(x) for x in range(0,10,2))])
U13-Forward
  • 69,221
  • 14
  • 89
  • 114
0

Modifying a collection (especially operations that modify the length) while iterating over it is a no-no. You're pulling the carpet out from underneath your feet as you remove elements.

If you did it backwards, it would work:

   for i in reversed(b):
       a.remove(i)
   print(a)
Jordan McQueen
  • 777
  • 5
  • 10