1

I have a list that contains more lists and zeros.

checks =[[1], [2, 6, 10, 9], [3, 7, 8], [4], [5], 0, 0, 0, 0, 0, [11]]

I intend to remove all the zeros and the lists having length one. I wrote the following code and expected the output to be:

checks = [[2,6,10,9], [3,7,8]]

instead, the output came out to be:

checks = [[2,6,10,9], [3,7,8], [5]]

code:

while 0 in checks:
    checks.remove(0)
    
for x in checks:
    if len(x) < 2:
        checks.remove(x)
        
print(checks)

Why is my code not removing the single element list [5] from the given list? I ran this piece of code on many IDEs, but the result was the same. Is it some flaw of Python or am I missing some key concept? It would be really helpful if someone can explain this behavior of Python and give a fix for the same.

Aman Sharma
  • 73
  • 10
  • 1
    Don't remove items from a list while you are iterating over it (as you are in your `for` loop) – alani Aug 07 '20 at 04:47
  • 1
    @Aman Sharma, in the ```for loop``` when you remove the items, not only the items are getting removed but also your list gets updated with it. But the ```x``` iterates over next index for every new iteration i.e. it doesn't check the same index next time. – Voldemort Aug 07 '20 at 05:01

3 Answers3

2

You should not remove items from a list while you are iterating over it with a for loop. You can achieve what you want using a while loop and an explicit index variable which you manipulate:

i = 0
while i < len(checks):
    if len(checks[i]) < 2:
        checks.pop(i)
    else:
        i += 1
alani
  • 12,573
  • 2
  • 13
  • 23
2

You can use list comprehension. And as @alaniwi suggested, it may not be a good idea to manipulate a list within a for loop of the list.

checks =[[1], [2, 6, 10, 9], [3, 7, 8], [4], [5], 0, 0, 0, 0, 0, [11]]

while 0 in checks:
    checks.remove(0)

checks = [x for x in checks if len(x) >= 2]

print(checks)
1

It's kind of a flaw of python. You should not iterate a list or dict or any container when you iterating over it.

The easy fix is to change for x in checks: to for x in list(checks): to create a copy of list (only the container, not the content, so it's very cheap operation).