0

I want to delete strings("324a" included) and leave only integers in a list. Here is the code;

a = ["345", "sadas", "324a", "14", "john"]
    

for i in a:
    try:
        if i == int(i):
            continue
    except ValueError:
        a.remove(i)
print(a)

With this code the output is;

['345', '324a', '14']

Even tho "324a" is not an integer and code should return ValueError the code still does not remove it from the list.


Here is another simple code that shows "324a" is not a integer;

a = "324a"
a = int(a)
print(a)

Output of the code above;

a = int(a)
ValueError: invalid literal for int() with base 10: '324a'

Thanks for the answers in advance!

5 Answers5

1

It has to do with you mutating the list while iterating over it.

Look at the code below and watch the printed index...you remove sadas at index 1 which now leaves 324a at index 1, but the loop doesn't recognize the value change and thus does not repeat index 1 twice during the iteration.

for idx, i in enumerate(a):
    print(idx)
    try:
        if i == int(i):
            continue
    except ValueError:
        a.remove(i)
print(a)

try -

a = ["345", "sadas", "324a", "14", "john"]
b = []
for i in a:
    try:
        int(i)
        b.append(i)
    except ValueError:
        continue
print(b)
hancho
  • 1,345
  • 3
  • 19
  • 39
1
mixed_array = ["345", "sadas", "324a", "14", "john"]
only_integers= [] 

# A method to check if an object is integer
def is_int(s):
    try: 
        int(s)
    except ValueError:
        return False
    else:
        return True

# Add integer objects from mixed_array to only_integers like:
only_integers = [i for i in mixed_array if is_int(i)]

# OR like:

only_integers = list(filter(is_int, mixed_array ))
Ahmad hassan
  • 1,039
  • 7
  • 13
  • 1
    I like this, but there's a few things that could be improved: 1) Use an else-clause to keep the try-clause as small as possible. 2) Don't use UpperCamelCase for function names, use snake_case or at least lowerCamelCase. 3) `isInt` is unnecesary when you can test the function result directly. 4) It's a bit simpler to use a comprehension or filter instead of a loop. [Here's a gist](https://gist.github.com/wjandrea/3fcc8bba2851393aa4467697ea614fb4) with the changes. – wjandrea Dec 27 '20 at 17:55
  • 1
    Nice! Also I forgot to mention, it would help to add a short explanation of how the code works, like just a sentence or two. – wjandrea Dec 27 '20 at 18:12
0

You can't shouldn't remove items from a list while iterating through it.
Also, when i is a str following statement will be False: i == int(i).
I suggest using this instead:

a = ["345", "sadas", "324a", "14", "john"]
tempList = []
for i in a:
    try:
        int(i)
        tempList.append(i) # if int(i) fails, this line won't be reached
    except ValueError:
        pass

a = tempList[:] # we use [:] to copy the list
print(a)

or this one-liner:

a = ["345", "sadas", "324a", "14", "john"]
print([int(x) for x in a if x.isdigit()])
cagri
  • 807
  • 8
  • 17
  • I can remove items from a list while iterating but this process messes the index. Here is why: https://stackoverflow.com/questions/6260089/strange-result-when-removing-item-from-a-list-while-iterating-over-it – devdevdev Dec 27 '20 at 17:53
0

Don't modify the list you are iterating. Create a new one instead like this:

a = list(filter(None, map(lambda x: x if x.isdigit() else None, a)))

Edit: From the comment, we can directly use str.isdigit with filter,

a = list(filter(str.isdigit, a)))
Jarvis
  • 8,494
  • 3
  • 27
  • 58
0

You could use a simple list comprehension like this:

a = [word for word in a if word.isdigit()]

And this will create a list with all the numbers.

wjandrea
  • 28,235
  • 9
  • 60
  • 81
Spiros Gkogkas
  • 432
  • 5
  • 11