Looping through list of functions in a function in Python dynamically
<p>I'd like to see if it's possible to run through a list of functions in a function. The closest thing I could find is looping through an entire module. I only want to use a pre-selected list of functions.</p>

<p>Here's my original problem:</p>

<ol>
<li>Given a string, check each letter to see if any of the 5 tests fulfill.</li>
<li>If a minimum of 1 letter passes a check, return True.</li>
<li>If all letters in the string fails the check, return False.</li>
<li>For each letter in the string, we will check these functions: isalnum(), isalpha(), isdigit(), islower(), isupper()</li>
<li>The result of each test should print to different lines. </li>
</ol>

<p>Sample Input</p>

<pre><code>    qA2
</code></pre>

<p>Sample Output (must print to separate lines, True if at least one letter passes, or false is all letters fail each test):</p>

<pre><code>    True
    True
    True
    True
    True
</code></pre>

<p>I wrote this for one test. Of course I could just write 5 different sets of code but that seems ugly. Then I started wondering if I could just loop through all the tests they're asking for. </p>

<p>Code for just one test:</p>

<pre><code>    raw = 'asdfaa3fa'
    counter = 0
    for i in xrange(len(raw)):
        if raw[i].isdigit() == True: ## This line is where I'd loop in diff func's
            counter = 1
            print True
            break
    if counter == 0:
        print False
</code></pre>

<p>My fail attempt to run a loop with all the tests:</p>

<pre><code>    raw = 'asdfaa3fa'
    lst = [raw[i].isalnum(),raw[i].isalpha(),raw[i].isdigit(),raw[i].islower(),raw[i].isupper()]
    counter = 0
    for f in range(0,5):
        for i in xrange(len(raw)):
            if lst[f] == True: ## loop through f, which then loops through i
                print lst[f] 
                counter = 1
                print True
        break
        if counter == 0:
    print False
</code></pre>

<p>So how do I fix this code to fulfill all the rules up there?</p>

<hr>

<p><strong>Using info from all the comments - this code fulfills the rules stated above, looping through each method dynamically as well.</strong></p>

<pre><code>    raw = 'ABC'
    functions = [str.isalnum, str.isalpha, str.isdigit, str.islower,  str.isupper]

    for func in functions:
        print any(func(letter) for letter in raw)
</code></pre>

<p><strong>getattr approach (I think this is called introspection method?)</strong></p>

<pre><code>    raw = 'ABC'

    meths = ['isalnum', 'isalpha', 'isdigit', 'islower', 'isupper']
    for m in meths: 
        print any(getattr(c,m)() for c in raw)
</code></pre>

<p><strong>List comprehension approach:</strong></p>

<pre><code>    from __future__ import print_function ## Changing to Python 3 to use print in list comp

    raw = 'ABC'
    functions = [str.isalnum, str.isalpha, str.isdigit, str.islower, str.isupper]
    solution = [print(func(raw)) for func in functions]
</code></pre>

<p>I'm going to guess that you're validating password complexity, and I'm also going to say that software which takes an input and says "False" and there's no indication <em>why</em> is user-hostile, so the most important thing is not "how to loop over nested char function code wizardry (*)" but "give good feedback", and suggest something more like:</p>

<pre><code>raw = 'asdfaa3fa'

import re

def validate_password(password):
    """ This function takes a password string, and validates it
        against the complexity requirements from {wherever}
        and returns True if it's complex enough, otherwise False """

    if not re.search('\d', password):
        print("Error: password needs to include at least one number")
        return False

    elif not re.search('[a-z]', password):
        print("Error: password must include at least one lowercase letter")
        return False

    elif not re.search('[A-Z]', password):
        print("Error: password must include at least one uppercase letter")
        return False

    print("Password is OK")
    return True

validate_password(raw)
</code></pre>

<p>Try online <a href="https://repl.it/D2Bm" rel="nofollow">at repl.it</a></p>

<p>And the regex searching checks ranges of characters and digits in one call, which is neater than a loop over characters.</p>

<p>(PS. your functions overlap; a string which has characters matching 'isupper', 'islower' and 'isnumeric' already has 'isadigit' and 'isalnum' covered. More interesting would be to handle characters like <code>!</code> which are not upper, lower, digits or alnum).</p>

<hr>

<p>(*) function wizardry like the other answers is normally exactly what I would answer, but there's so much of that already answered that I may as well answer the other way instead :P</p>

python list loops