0

Not super experienced, but I'm running into what looks like an error while using the isdigit() method.

I am trying to go through a list and remove all non-numbers, however my final list keeps giving me some letters. Not sure if this is a bug or I'm doing something wrong.

Here is my current python:

Python 3.6.1 (v3.6.1:69c0db5050, Mar 21 2017, 01:21:04) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin

My code:

>>> test
['b', 'd', 'f', 'h', 'j', 'l', 'x', '2']
>>> for i in test:
if not i.isdigit():
    print(i, "should not be a digit")
    test.remove(i)


b should not be a digit
f should not be a digit
j should not be a digit
x should not be a digit
>>> test
['d', 'h', 'l', '2']

Here I would expect to only have 2 in my final list. Am I doing things wrong?

yeahb2018
  • 5
  • 2
  • 1
    You are modifying the list while iterating it...that's not going to end well. – Andrej Kesely Aug 05 '18 at 20:45
  • Good catch, I did not think there'd be issues, but I guess it makes sense since the list loaded at the beginning of the iteration kept changing. I would possibly expect some kind of exception. Great for learning though! – yeahb2018 Aug 05 '18 at 20:55

2 Answers2

2

If you want to filter out on a isdigit test:

test = list(filter( lambda x : x.isdigit(), test))

As said in the comments removing element whilst iterating is bad practice.

Learning is a mess
  • 7,479
  • 7
  • 35
  • 71
  • 1
    This'll return an iterator so you may want to wrap in `list`. Also `filter(str.isdigit, test)` and `(c for c in test if c.isdigit())` are probably cleaner. – FHTMitchell Aug 05 '18 at 20:51
  • Have added the list constructor, indeed `filter` returns an iterator in Python3. – Learning is a mess Aug 05 '18 at 20:54
  • This does work, as a learner, can you provide a few more details why this method behaves differently than my loop? Or point me into some reading material? – yeahb2018 Aug 05 '18 at 20:57
  • You don't need a lambda function just to call a method. It is redundant. – khelwood Aug 05 '18 at 20:57
0

when you iterate over the list the first time, it uses the first item b. Now the for loop expects the second value, however since you removed b, d is now first and f second. In this way, d is ignored and is why it's in the final result. Try this:

test = [i for i in test if not i.isdigit()]
for i in test:
    print(i, 'must be a digit')

Adapt to your need

N Chauhan
  • 3,407
  • 2
  • 7
  • 21