Q:

Looped Module Return (Python 2.7.10)

I stumbled across a fix for my problem, though I do not quite understand why it works. For reference, "users" refers to a dictionary { 'username' : 1234 } where "1234" is the User ID.
First Attempt:

users = users_found()

def target_user():
    for key in users.keys():
        print key

    target = raw_input("Which user do you want to target? ").lower()

    try:
        print users[target], target

        return users[target], target

    except KeyError:
        print "No such user was listed"

        target_user()

target, username = target_user()

The above did not work, against my better understanding and returned

TypeError: 'NoneType' object is not iterable

referencing the very last line, of the variable assignment.
However, to check if 'target' was a 'NoneType' I inserted the print statement and this showed the values I was expecting even though the proceeding return seemed to be looking somewhere else using the same variables.
So naturally (really have no idea why) I tried a while loop instead.
Second Attempt:

users = users_found()

def target_user():
    for key in users.keys():
        print key

    target = raw_input("Which user do you want to target? ").lower()

    while target not in users.keys():
        print "No such user was listed"

        for key in users.keys():
            print key

        target = raw_input("Which user do you want to target? ").lower()

    return users[target], target

target, username = target_user()

This works and returns both values.
I am assuming it is something to do with the fact the while loop does not call for the method again, but that does not explain why the "print" statement worked as expected.
I would greatly appreciate it if somebody would shed some light as to my illogic here.
Thank you.

A:

While other answerers are right that recursion is not really the right solution to your problem, the actual error you are getting is because you do not return the value from the recursive call. So, if the user ever types in a non-existent name, and the except clause calls the recursion, the only thing that is returned to the top level is None, which as the error says is not iterable. To fix this, just make sure you always return a value:
except KeyError:
    print "No such user was listed"

    return target_user()

But, again, recursion is not the way to solve this problem. Apart from anything else, a really perverse user could quite easily type in nonsense enough times to reach the maximum recursion depth, causing an error.

