Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getting only positive number from a list that containing heterogeneous data type item in python 3

Tags:

python

list

I have a list of items with heterogeneous data types contained in strings.

lst=['1','err','-1',' ','155']

From that, I would like to obtain a new list with only the positive numbers: new_lst=[1,155]

I have tried to avoid negative numbers as shown below. However, I am not able to avoid the strings and empty strings:

lst1=int(lst)
for i in lst1:
    if i<0:
    print i
    else:
    continue

Traceback (most recent call last):
  File "C:/Users/Dev/Documents/Assignment-2/test-2.py", line 22, in <module>
    c3=int(row[3])
ValueError: invalid literal for int() with base 10: 'err'
>>> 
like image 380
Anil Kumar Gupta Avatar asked Oct 16 '15 18:10

Anil Kumar Gupta


4 Answers

lst=['1','err','-1',' ','155']
newlst = []
for i in lst:
    try:
        if int(i) >= 0:
            newlst.append(int(i))
    except ValueError:
        pass
like image 173
BigZ Avatar answered Nov 15 '22 09:11

BigZ


lst1=int(lst) is the code that is raising the exception. This is essentially trying to cast a list into an int (which you cannot do).

What you want to do is iterate through lst, and for each element, determine if the element can be cast into an int, then check if the element (as an int) is positive.


You could do something like this:

lst = ['1','err','-1',' ','155']
new_lst = []

for i in lst:
    try:
        int_i = int(i)           # try to cast i to an int
        if int_i > 0:
            new_lst.append(int_i)
    except ValueError:           # ValueError is raised, i cannot be cast into an int
        pass                     # continue to the next element

EDIT: Added ValueError for completeness, see @BigZ's answer.

like image 30
budi Avatar answered Nov 15 '22 09:11

budi


Here is a one liner that tests if an element is actually a number. If this check isn't done, int(x) will not work and throw and exception.

lst=['1','err','-1',' ','155']
lst1 = filter(None,[(lambda x: x if x.isdigit() and int(x) > 0 else None) (x) for x in lst])
like image 37
keda Avatar answered Nov 15 '22 07:11

keda


If you just have ints and considering you only want to keep positive numbers str.isdigit is sufficient as you don't care if "-1" fails on str.isdigit:

lst[:] = (ele for ele in lst if ele.isdigit() and int(ele) > 0)

If you did possibly have floats then all the answers using int and a try/except would also fail, if you want to cover "1.0" etc.. you would need to cast to float in the try.

like image 21
Padraic Cunningham Avatar answered Nov 15 '22 07:11

Padraic Cunningham