1

Assume I'd like to convert a list of strings to integer, but it cannot be done for all elements.

I know this works:

a = ['2.0','3.0','4.0','5.0','Cherry']
b = []

for k in a:
    try:
        int(k)
        b.append(int(k))
    except:
        pass

print b
> [2, 3, 4, 5]

But is there also a shorter way of doing this? I thought about something like:

b = [try int(k) for k in a]

This may sound like a silly question since I do have a working solution, but I have often been shown shorter ways of doing the same thing and always appreciated this kind of help. I am using Python 2.7

Thanks!

Edit: sorry, I was also talking about floating point. I just changed my example data

gariepy
  • 3,576
  • 6
  • 21
  • 34
offeltoffel
  • 2,691
  • 2
  • 21
  • 35

3 Answers3

3

There is no way to use try/except clauses inside List Comprehensions but this could help:

a = ['2','3','4','5','Cherry']
print [int(x) for x in a if x.isdigit()]

Output:

['2', '3', '4', '5']

Update (as the question was updated):

This could help but I don't know how good/accurate is to use it:

a = ['2.0','3.0','4.0','5.0', '44545.45', 'Cherry']

[float(x) for x in a if x.split('.')[0].isdigit() and x.split('.')[1].isdigit()]

Output:

[2.0, 3.0, 4.0, 5.0, 44545.45]
Andrés Pérez-Albela H.
  • 4,003
  • 1
  • 18
  • 29
0

Try this one.

def is_number(k):
    try:
        float(k)
    except ValueError:
        return False
    return True

[int(float(k)) for k in a if is_number(k)]
Andrii Rusanov
  • 4,405
  • 2
  • 34
  • 54
0

If you want to compress try-except into one line then i think answer is NO and it is answered at here. I would go with mix of regex and isinstance check-It captures all number types e.g. float, long, int and complex-

>>>a=['2', '3', '4', '5', 'Cherry', '23.3', '-3']
>>>filter(bool,[i if isinstance(eval(i),(int, long, float, complex)) else None for i in filter(lambda x: re.findall(r'[-+]?\d+[\.]?\d*',x),a)])
>>>['2', '3', '4', '5', '23.3', '-3']

If you want to capture only floats-

>>>filter (bool,[i if isinstance(eval(i),float) else None for i in filter(lambda x: re.findall(r'[-+]?\d+[\.]?\d*',x),a)])
>>>['23.3']

If you want to capture only int-

>>>filter (bool,[i if isinstance(eval(i),int) else None for i in filter(lambda x: re.findall(r'[-+]?\d+[\.]?\d*',x),a)])
>>>['2', '3', '4', '5', '-3']
Community
  • 1
  • 1
Learner
  • 5,192
  • 1
  • 24
  • 36