# String validation based on multiple criteria

I had me a code challenge and I was thinking: is there a way to make this more efficient and short? The challenge requires me to scan a string and ...

• In the first line, print True if it has any alphanumeric characters. Otherwise, print False.

• In the second line, print True if it has any alphabetical characters. Otherwise, print False.

• In the third line, print True if it has any digits. Otherwise, print False.

• In the fourth line, print True if it has any lowercase characters. Otherwise, print False.

• In the fifth line, print True if has any uppercase characters. Otherwise, print False.

Below is my approach :

def func_alnum(s):
for i in s:
if i.isalnum():
return True
return False

def func_isalpha(s):
for i in s:
if i.isalpha():
return True
return False

def func_isdigit(s):
for i in s:
if i.isdigit():
return True
return False

def func_islower(s):
for i in s:
if i.islower():
return True
return False

def func_isupper(s):
for i in s:
if i.isupper():
return True
return False
if __name__ == '__main__':
s = input()
s=list(s)
print(func_alnum(s))
print(func_isalpha(s))
print(func_isdigit(s))
print(func_islower(s))
print(func_isupper(s))


It feels like I made a mountain out of a molehill. But I would defer to your opinions on efficiency and shortness before I live with that opinion.

Your five functions only differ by the predicate used to test each character, so you could have a single one parametrized by said predicate:

def fulfill_condition(predicate, string):
for character in string:
if predicate(character):
return True
return False

if __name__ == '__main__':
s = input()
print(fulfill_condition(str.isalnum, s))
print(fulfill_condition(str.isalpha, s))
print(fulfill_condition(str.isdigit, s))
print(fulfill_condition(str.islower, s))
print(fulfill_condition(str.isupper, s))


Note that you don't need to convert the string to a list for this to work, strings are already iterables.

Now we can simplify fulfill_condition even further by analysing that it applies the predicate to each character and returns whether any one of them is True. This can be written:

def fulfill_condition(predicate, string):
return any(map(predicate, string))


Lastly, if you really want to have 5 different functions, you can use functools.partial:

from functools import partial

func_alnum = partial(fulfill_condition, str.isalnum)
func_isalpha = partial(fulfill_condition, str.isalpha)
func_isdigit = partial(fulfill_condition, str.isdigit)
func_islower = partial(fulfill_condition, str.islower)
func_isupper = partial(fulfill_condition, str.isupper)

• Thanks. It helps to know other efficient approach to solve a problem. :) – mishsx Jul 10 at 7:11

This is done using list comprehensions and any() in python.

We can use the following to make it more faster.

print(any([i.isalnum() for i in string]))


Since we are only looking for any 1 element in the string being an uppercase,lowercase, etc Any() finds a good use case here.

• any can also take an iterator instead of a list. It stops the iteration as soon as it encounters a True element. So if you remove the square brackets, it's even faster. – Matthias Huschle Jul 9 at 16:04