Search code examples
pythonfor-loopif-statementreturngenerator

Python returns generator object without yield


I am trying to generate a function which tells me if a word is an isogram (contains duplicate values). However, this code always returns a generator object.

def is_isogram(string):
    return (True if (string.lower().count(letter) == 1) else False for letter in string.lower())

I know how to solve the problem, I was just wondering what is wrong with my code.


Solution

  • I suppose your function is intended to return a boolean, but the return statement has an iteration happening, where each value is mapped to a boolean. The parentheses give you an iterator over those booleans. The function's description suggests that the function should return True when the input has duplicate letters, but the mapping gives True when a letter is not duplicate. So you have three problems:

    • The iterator
    • The multiple booleans, when you want one boolean
    • The booleans indicate the inverse of what you want to return

    So your idea for an algorithm should be changed to this:

    def is_isogram(string):
        return any(letter for letter in string.lower() if string.lower().count(letter) > 1)
    

    Side note: this algorithm is not efficient. More efficient is to create a set:

    def is_isogram(string):
        return len(set(string.lower())) < len(string)