Recording loans of access cards to people in a company
Inline comments should only be used sparingly, and definitely not on already long lines. Your #returns a list of objects is pretty unnecessary both because it's overly long, but also because it's inferrable and doesn't seem to matter. You only pass the loans on unchanged so the user doesn't care that they're a list of objects. You can infer that it's a collection of something because of the name loans and the len usage. And that's all you need to know in this function, so forget that comment.

You should also format your docstring so it contains just one line summarising the function, a blank line and then the further details. You just have one long block but it's hard to read from it what the function should do. Instead you detail the possible results.

Instead of using str and concatenation, just use str.format. It's a convenient way of formatting strings and coverting their type at the same time:

    successMsg = "Card {} has been marked as returned".format(value)


Also note that you haven't correctly inserted this value in the failureMsg of numLoans &gt; 1. You just have the string literal " + str(value) + ". You'd need the extra quotation marks to do it your way:

    failureMsg = """
    More than one loan for """ + str(value) + """ exists. Please select
    the correct loan to return from the next screen.
    """


But instead I'd suggest using str.format again.