-1

I am trying to remove numbers that have more length than 1. But it is skipping one of them. Can anyone explain why is it happening and how can i prevent it from happening in future?

a =[3, 4, 5, 6, 54, 43, 543]
for m in a:
    if len(str(m))>1:
        a.remove(m)
print(a)
Output>>> [3, 4, 5, 6, 43]
Expected Output>>> [3, 4, 5, 6]
Kyoko Sasagava
  • 113
  • 1
  • 8
  • Does this answer your question? [Python remove elements that are greater than a threshold from a list](https://stackoverflow.com/questions/59925384/python-remove-elements-that-are-greater-than-a-threshold-from-a-list) – Trenton McKinney Aug 31 '20 at 02:23
  • 3
    Please don't operate the list while you are iterating it. – jizhihaoSAMA Aug 31 '20 at 02:24
  • 2
    A more efficient comparison: `if m >= 10:` – Ry- Aug 31 '20 at 02:24
  • `len(str(int))` may become error-prone if your list contains negative ints: `len(str(-1)) == 2` – Chris Aug 31 '20 at 02:30
  • 1
    I think this question is duplicate with this one https://stackoverflow.com/questions/1207406/how-to-remove-items-from-a-list-while-iterating – echnyee Aug 31 '20 at 02:34
  • I agree with @jizhihaoSAMA. You are changing the list while looping through it. I would suggest a safer solution with `[i for i in a if len(str(i)) == 1]` – metinsenturk Aug 31 '20 at 02:35
  • @jizhihaoSAMA i found my answer. Thank you though. Using while loop with if else statement works better – Kyoko Sasagava Aug 31 '20 at 02:53

3 Answers3

2

One line list comprehension

a = [n for n in a if n < 10]

Or you can replace the for loop to while loop as follows. For loop gets kinda problematic when changing the length and deleting elements, so it's better to use a while loop instead.

while i < len(a):
    if len(str(a[i])) > 1:
        a.pop(i)
    else:
        i+=1
print(a)
Marsilinou Zaky
  • 1,038
  • 7
  • 17
1

I fixed your code;

a = [3, 4, 5, 6, 54, 43, 543]
b = a.copy()
for m in a:
    if len(str(m))>1:
        b.remove(m)
print(b)

Let me explain why the bug happens. For example, if you remove 5th element - 54 in the middle of for loop, 43 is shifted left to the 5th place and 543 is shifted left to the 6th place. So in the next loop(6th), the loop pointer goes to 543; it means that the loop pointer skips 43.

Ahmed Mamdouh
  • 696
  • 5
  • 12
0

don't edit a list inside a loop

a =[3, 4, 5, 6, 54, 43, 543]
b = []
for m in a:
    if len(str(m))<=1:
        b.append(m)
print(b)
barker
  • 1,005
  • 18
  • 36