Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: string to int or zero on error, without try/except

Tags:

python

In the spirit of short code... I have a list of either numbers or empty strings and I want to map(int, mylist) without it failing.

mylist = "123//456".split("/") #['123', '', '456']
myints = <something to quickly convert the list>

EDIT I need to keep the same number of tokens. I.e. myints = [123, 0, 456].

I was thinking of something along the lines of map(lambda x: int(x) or 0, mylist), but of course this still throws a ValueError. Any ideas?


Another EDIT

Some results (timing for xrange(1000000))...

  • 2.03s l = map(lambda x: x.isdigit() and int(x) or 0, mylist)
  • 1.37s l = [x.isdigit() and int(x) or 0 for x in mylist]
  • 1.99s l = map(lambda x: int(x) if x.isdigit() else 0, mylist)
  • 1.35s l = [int(x) if x.isdigit() else 0 for x in mylist]
  • 1.24s l = [int(x or 0) for x in mylist]
  • 1.45s l = [int(e) if e.strip() else 0 for e in mylist]
  • 4.44s the big chunk of code with try/except ergo bigger is slower :) ok, not always

Just included these for their time as they don't produce the desired output...

  • 3.71s l = map(int, re.findall('[0-9]+', "123//456")) ('course regex is slow. time&place)
  • 1.47s l = map(int, filter(None, mylist))
  • 1.15s [int(x) for x in mylist if x] (nice time!)

*I should mention re.compile shaves 3.71s down to 2.11s.

Python 2.7.3, Xeon E5-1607

myints = [int(x or 0) for x in mylist] is not only the fastest with the correct result but also VERY short at 29 characters.

Thanks all for your input! Not so much the downvoters :P

like image 704
jozxyqk Avatar asked Jan 28 '26 02:01

jozxyqk


2 Answers

Short, though not as robust as other answers -- x must be an empty string or a number:

[int(x or 0) for x in mylist]
like image 78
Janne Karila Avatar answered Jan 29 '26 19:01

Janne Karila


Short isn't always the best, but this is pretty short:

>>> [int(e) if e.strip() else 0 for e in "123//456".split("/")]
[123, 0, 456]

Also:

>>> map(int, (e if e.isdigit() else '0' for e in "123//456".split("/")))
like image 35
dawg Avatar answered Jan 29 '26 18:01

dawg