-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]
  • 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
  • FYI: Thoroughly answering questions is time-consuming. If your question is **solved**, say thank you by _**accepting** the solution that is **best for your needs**._ The **accept check** is below the up/down arrow at the top left of the answer. A new solution can be accepted if a better one shows up. You may also vote on the quality/helpfulness of an answer, with the up or down arrow, if you have a 15+ reputation. **Leave a comment if a solution doesn't answer the question.** [What should I do when someone answers my question?](https://stackoverflow.com/help/someone-answers). Thank you. – Trenton McKinney Aug 31 '20 at 03:57

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,028
  • 6
  • 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
  • 686
  • 2
  • 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
  • 953
  • 16
  • 33