Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a better way to find if string contains digits?

Tags:

python

string

I'm working with strings that contain both digits and alphanumerics, or just digits, but not just alphas. In order to test for false matches, I need to check if the strings contain at least one digit, printing an error message if it doesn't. I have been using the following code:

s = '0798237 sh 523-123-asdjlh'

def contains_digits(s):
    for char in list(s):
        if char.isdigit():
            return True
            break
    return False

if contains_digits(s) == True:
    print s
else:
    print 'Error'

Is there a more pythonic or simpler way to do so, or does this suffice? Also, I can't just check to see if the string is alphanumeric, because the string may contain various symbols ('-', spaces, etc.)

like image 531
aensm Avatar asked Jun 27 '12 18:06

aensm


People also ask

How do I check if a string contains digits?

To find whether a given string contains a number, convert it to a character array and find whether each character in the array is a digit using the isDigit() method of the Character class.

How do you check if a string ends with a number?

To check if a string ends with a number, call the test() method on a regular expression that matches one or more numbers at the end a string. The test method returns true if the regular expression is matched in the string and false otherwise.


2 Answers

This is one of those places where a regular expression is just the thing:

_digits = re.compile('\d')
def contains_digits(d):
    return bool(_digits.search(d))

Little demo:

>>> _digits = re.compile('\d')
>>> def contains_digits(d):
...     return bool(_digits.search(d))
... 
>>> contains_digits('0798237 sh 523-123-asdjlh')
True
>>> contains_digits('sh asdjlh')
False

You could use the any method with .isdigit() as described in @Wallacolloo's answer, but that's slower than the simple regular expression:

>>> import timeit
>>> timeit.timeit("contains_digits('0798237 sh 523-123-asdjlh')", 'from __main__ import contains_digits')
0.77181887626647949
>>> timeit.timeit("contains_digits_any('0798237 sh 523-123-asdjlh')", 'from __main__ import contains_digits_any')
1.7796030044555664

The if method is on par with the regular expression:

>>> timeit.timeit("contains_digits_if('0798237 sh 523-123-asdjlh')", 'from __main__ import contains_digits_if')
0.87261390686035156

But things get worse if the digits appear late in the text:

>>> timeit.timeit("contains_digits('asdjlhtaheoahueoaea 11 thou')", 'from __main__ import contains_digits')
1.202538013458252
>>> timeit.timeit("contains_digits_any('asdjlhtaheoahueoaea 11 thou')", 'from __main__ import contains_digits_any')
5.0348429679870605
>>> timeit.timeit("contains_digits_if('asdjlhtaheoahueoaea 11 thou')", 'from __main__ import contains_digits_if')
3.707183837890625

Timings tested on python 2.6 on Mac OS X 10.7.

like image 188
Martijn Pieters Avatar answered Sep 20 '22 22:09

Martijn Pieters


Use the any function, passing in a sequence.
If any element of the sequence is true (ie is a digit, in this case), then any returns True, else False. https://docs.python.org/library/functions.html#any

def contains_digits(s):
    return any(char.isdigit() for char in s)

If you're concerned about performance though, your current method is actually faster.

like image 40
Ponkadoodle Avatar answered Sep 17 '22 22:09

Ponkadoodle