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)