Does anybody have a quickie for converting an unsafe string to an int?
The string typically comes back as: '234\r\n' or something like that.
In this case I want 234. If '-1\r\n', I want -1. I never want the method to fail but I don't want to go so far as try, except, pass just to hide errors either (in case something extreme happens).
-
6"I never want the method to fail but I don't want to go so far as try, except, pass just to hide errors" That certainly seems contradictory. "Never Fail" means "Catch Exceptions". What do you mean by "Never Fail" and "NOT Catch Exceptions"? What is this no-failure, no-exception thing you're expecting? Can you clarify your expectations?S.Lott– S.Lott2010年03月24日 15:33:35 +00:00Commented Mar 24, 2010 at 15:33
8 Answers 8
In this case you do have a way to avoid try/except, although I wouldn't recommend it (assuming your input string is named s, and you're in a function that must return something):
xs = s.strip()
if xs[0:1] in '+-': xs = xs[1:]
if xs.isdigit(): return int(s)
else: ...
the ... part in the else is where you return whatever it is you want if, say, s was 'iamnotanumber', '23skidoo', empty, all-spaces, or the like.
Unless a lot of your input strings are non-numbers, try/except is better:
try: return int(s)
except ValueError: ...
you see the gain in conciseness, and in avoiding the fiddly string manipulation and test!-)
I see many answers do int(s.strip()), but that's supererogatory: the stripping's not needed!
>>> int(' 23 ')
23
int knows enough to ignore leading and trailing whitespace all by itself!-)
18 Comments
int, which hasn't changed in 10 years or more!import re
int(re.sub(r'[^\d-]+', '', your_string))
This will strip everything except for numbers and the "-" sign. If you can be sure that there won't be ever any excess characters except for whitespace, use gruszczy's method instead.
1 Comment
int('243\r\n'.strip())
But that won't help you, if something else than a number is passed. Always put try, except and catch ValueError.
Anyway, this also works: int('243\n\r '), so maybe you don't even need strip.
EDIT:
Why don't you just write your own function, that will catch the exception and return a sane default and put into some utils module?
Comments
try:
x=int("234\r\n".strip())
except ValueError:
x=0
2 Comments
def str_to_int(a):
str_to_int_output=""
for i in range(len(a)):
for b in range(10):
if a[i]==str(b):
str_to_int_output+=a[i]
return int(str_to_int_output)
fn for "str to float" is a bit more comlicated, but i think i can do it if it is needed.
Comments
You could just:
def to_int(unsafe_string):
return int(unsafe_string.strip())
But it will throw a ValueError if the stripped unsafe_string is not a valid number. You can of course catch the ValueError and do what you like with it.
3 Comments
int('234\r\n') works without strip, so my function here is completely redundant.Without knowing what kinds of inputs you are expecting, it's hard to say what is 'enough' to solve this. If you are just worried about trailing newlines, then Xavier Combelle's or gruszczy's answer is enough:
try:
x = int(value)
except ValueError:
x = 0
If you have to find any integer, anywhere in a string, then you might need something like this:
import re
try:
x = int(re.search(r'(0|(-?[1-9][0-9]*))', searchstring).group(0))
except TypeError: # Catch exception if re.search returns None
x = 0
Comments
Under Python 3.0 (IDLE) this worked nicely
strObj = "234\r\n"
try:
#a=int(strObj)
except ValueError:
#a=-1
print(a) >>234
If you're dealing with input you cannot trust, you never should anyway, then it's a good idea to use try, except, pass blocks to control exceptions when users provide incompatible data. It might server you better to think about try, except, pass structures as defensive measures for protecting data compatibility rather than simply hidding errors.
try:
a=int(strObj) #user sets strObj="abc"
except ValueError:
a=-1if a != -1:
#user submitted compatible data
else:
#inform user of their error
I hope this helps.