DEV Community

Erik Anderson
Erik Anderson

Posted on

How did they do that in one line? Part 2: Isograms

I just solved another challenge on Codewars, and, like in my previous post, the most popular solution used far fewer lines than mine did.

The challenge for this kata is to take a string and indicate whether it's an isogram. An isogram is a word with no repeating letters.

Here's the popular solution:

def is_isogram(string):
    return len(string) == len(set(string.lower()))
Enter fullscreen mode Exit fullscreen mode

And here's mine

def is_isogram(string):
    result = False
    string = string.lower()
    my_list = []
    for character in string:
        if character in my_list:
            return False
        my_list.append(character)
    return True
Enter fullscreen mode Exit fullscreen mode

Wow. Big difference.

Let's pick apart that short solution.

def is_isogram(string):
    return len(string) == len(set(string.lower()))
Enter fullscreen mode Exit fullscreen mode

The right side of the equality test is simple enough. It's just the length of the string. The right side is a little more dense but it's not actually that bad. Its function is to calculate the length of the set of unique elements in string.

Let's see how it does that.

First, string.lower is necessary because there may be upper and lower case instances of the same letter, and the program should recognize these as being the same letter.

Next, set(string.lower()) gives us a set data type with all the unique elements in string. That is, if the letter b occurs twice in string, it will only occur once in the set.

Then len(set(string.lower())) calculates the length of this set.

We're now ready to consider the == comparison. If the length of the string is equal to to the length of the set, the function will return True, indicating that string is an isogram. On the other hand, if the length of the set is different from the length of the string, that means at least one letter occurs at least twice in string. The function will then return False, because string is not an isogram.

As a final note, it's interesting to consider the case where string is the empty string. In that case, both the length of the set and the length of the string are zero, so the function will return True.

Fortunately, the instructions indicate that we should assume an empty string is an isogram.

That's convenient. It means we don't need extra code to handle the case of an empty string. The function body stays at a pithy one line.

So there it is. A challenge I solved with 8 lines of function body could be accomplished with just 1.

Discussion (5)

Collapse
deciduously profile image
Ben Lovy

Wow, set() is super concise. Every time I read something new about Python I get envious.

Collapse
ekand profile image
Erik Anderson Author

lol
I've just started an computer science course in java, and that really emphasizes how much I love Python.

Collapse
ccombe profile image
Chris

wow you are keen to give yourself a challenge, why not Kotlin or Scala if you are going down that path...

Thread Thread
ekand profile image
Erik Anderson Author

Short answer: The Computer Science Certificate I want to do uses it.

Collapse
salabim profile image
Ruud van der Ham

Nice explanation.
Here's another, by far not as elegant as yours, one liner:

def is_isogram(string):
    return not any(c in string.lower()[i + 1:] for i, c in enumerate(string.lower()))