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.)
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With