Domanda

How can I determine if a string can be an integer in Python. For example: if I write functions named digit() and nondigit(). The string must be either just digits (1-9) or letters.

str1 = '4582'
str1.digit() == True
str2 = '458dfr'
str2.digit() == False
str3 = 'abcd'
str3.nondigit() == True
str4 = '258edcx'
str4.nondigit() == False
È stato utile?

Soluzione

str objects have an isdigit method which accomplishes one of your tasks. From a broader perspective, it's better to just try it and see:

def digit(s):
    try:
        int(s)
        return True
    except ValueError:
        return False

For example, " 1234 ".isdigit() is False (there are spaces), but python can convert it to an int, so my digit function is True.

Altri suggerimenti

There's a builtin for that.

'4582'.isdigit() == True
'458dfr'.isdigit() == False

"Under the hood" this probably looks a lot like:

def isdigit(self):
    return all(ch in "0123456789" for ch in self)

That said, if you're trying to USE it as an int, just use it as an int.

data = "123456"
try:
    data = int(data)
except ValueError:
    # handle this if your data is not a number

Never test for something to see if it's able to be transformed THEN try to transform it. This goes for int casts as well as checking for the existence of a file before opening it. It creates a race condition where if data can be turned to a number when you check but then another thread takes over and changes it before it gets cast to int you get an error. Similarly with files if you check that the file exists but something deletes it before it can be opened, you're SOL.

Instead, do the thing you're trying to do, and "ask forgiveness" if it causes an error. It's Easier to Ask Forgiveness than Permission.

Use .isdigit() for a built-in way to do that.

>>> string = 'hello'
>>> num = '98'
>>> string.isdigit()
False
>>> num.isdigit()
True
>>> 

You can also create your own function:

>>> def digit(num):
...     try:
...             int(num)
...             return True
...     except ValueError:
...             return False
... 
>>> digit('45')
True
>>> digit('hello')
False
>>> 

I now benchmarked the different approaches. is.digit() is way faster, and depending on what you do with it (e.g., large iterations) it might be worthile using it over an own function. (And it looks prettier btw.)

I put it into a IPython notebook if you want to run it on your machine:

And here are the results if:

import timeit

def string_is_int(a_str):
    try:
        int(a_str)
        return True
    except ValueError:
        return False

an_int = '123'
no_int = '123abc'

%timeit string_is_int(an_int)
%timeit string_is_int(no_int)
%timeit an_int.isdigit()
%timeit no_int.isdigit()

1000000 loops, best of 3: 401 ns per loop
100000 loops, best of 3: 3.04 µs per loop
10000000 loops, best of 3: 92.1 ns per loop
10000000 loops, best of 3: 96.3 ns per loop

Also, I have tested the more general case:

import timeit

def string_is_number(a_str):
    try:
        float(a_str)
        return True
    except ValueError:
        return False

a_float = '1.234'
no_float = '123abc'

a_float.replace('.','',1).isdigit()
no_float.replace('.','',1).isdigit()


%timeit string_is_number(an_int)
%timeit string_is_number(no_int)
%timeit a_float.replace('.','',1).isdigit()
%timeit no_float.replace('.','',1).isdigit()

1000000 loops, best of 3: 400 ns per loop
1000000 loops, best of 3: 1.15 µs per loop
1000000 loops, best of 3: 452 ns per loop
1000000 loops, best of 3: 394 ns per loop
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top