Explain Codes LogoExplain Codes Logo

How can I check if a string represents an int, without using try/except?

python
functions
best-practices
performance
Anton ShumikhinbyAnton Shumikhin·Nov 2, 2024
TLDR

To directly check if a string represents an integer, you can use this function checking for a minus or plus sign and any digit combination.

def is_int(s): # All we have to do is just check this...no big deal...right? if not s: return False return s[0] == '-' and s[1:].isdigit() if s[0] in '-+' else s.isdigit() # Usage print(is_int("-123")) # True - Yes, it loves negativity print(is_int("+123")) # True - Always positive! print(is_int("123")) # True - And it's neutral as well print(is_int("abc")) # False - Sorry, no alphabet soup today

Note: It doesn' handle numbers formatted as '+000123' or having leading zeros. It assumes that such numbers are not valid integers.

Variety is the spice of life: Accommodating different number formats

When dealing with different types of numbers presented as strings, understanding the specific nuances is crucial.

Playing nice with negative numbers

Negative numbers in string format will start with a '-'. So, our function should cater to this:

def is_negative_int(s): # Do you have a '-' ? Yes? Then let's dance! return s.startswith('-') and s[1:].isdigit()

Steering clear of the decimal dilemma

To avoid considering strings like '16.0' as an integer, we should ensure no decimal point exists:

def is_pure_integer(s): # Sorry, no decimal guests allowed in this integer party return s.replace('-', '', 1).isdigit() and '.' not in s

The power of regular expressions

Regular Expressions are like the Swiss army knife of validation. You can employ them to validate almost everything, including integer strings:

import re def is_valid_integer(s): # Yes, I can check everything...even the signs of an integer pattern = re.compile(r'^[+-]?[1-9]\d*|0$') return bool(pattern.match(s))

Craftier checks for edge cases and performance

While string methods are fast and efficient, regular expressions offer a more powerful tool for tackling more complex scenarios.

Avoiding the floating point trap

We need to ensure a clean distinction between integers and floats – and avoid methods like int() truncating floating-point numbers:

def is_strictly_integer(s): # I said Integers ONLY! No floats here, please. return s.lstrip('-').isdigit() and not any(char in s for char in '.eE')

The performance of C-style string scanning

For an ultra-efficient, single-pass check, we can loop through each character, looking at it from a C-style string scanning perspective:

def is_cstyle_int(s): # Do I look like I have time for non-digit characters? if not s or (len(s) == 1 and s in '-+'): return False return all(c.isdigit() for c in s.lstrip('-+'))