Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Python Collections (2016, retired 2019) Lists Disemvowel

Spencer Hill
Spencer Hill
1,397 Points

Can't get disemvowel to work?

Any suggestions as to why this doesn't work? :( Cheers.

disemvowel.py
def disemvowel(word):
    vowels = ["a", "e", "i", "o", "u"]
    wordList = list(word)
    try:
        for letter in wordList:
            for vowel in vowels:
                if letter == vowel.upper() or letter == vowel.lower():
                    wordList.remove(letter)
        word = join(wordList)
    except ValueError:
        pass
    return word

1 Answer

Greg Kaleka
Greg Kaleka
39,021 Points

Oh boy this was tricky.

First problem, which I saw right away and was so proud of myself: check out the docs on how to use String.join() - it's a bit of an awkward API if you ask me. You need to choose the string you want to use to join (often a comma - in this case, just an empty string), and then call join on that string, taking the list as an argument:

join.py
''.join(wordList)

That doesn't fix it, though (it does give you a different error message, though). So now what's happening...

I wrote your solution into a python script and added some print statements for debugging (note there's no need for a try: except: block):

disemvowel.py
def disemvowel(word):
    vowels = ["a", "e", "i", "o", "u"]
    wordList = list(word)
    for letter in wordList:
        print("letter: " + letter)
        for vowel in vowels:
            if letter == vowel.upper() or letter == vowel.lower():
                wordList.remove(letter)
                print("removed: " + letter)
    word = ''.join(wordList)
    return word

What this helped me realize is that you are changing the array while looping through it. This is a Very Bad Idea, and you should avoid doing it. The problem arrises when you have two vowels in a row. If we run this function on "Friends", the print output is:

letter: F
letter: r
letter: i
removed: i
letter: n
letter: d
letter: s

and the function returns Frends. See what's happening? When you remove the letter i, the loop moves on to what it thinks is the next letter, but you've sort of pulled the rug out from under it, and it goes to n, skipping over e. It goes from wordList[2] to wordList[3] but by the time it gets there, wordList[3] is

So, how do we fix this. Well, the smallest change to your code would be to simply add another list equal to list(word) as well, and manipulate that one while you loop through the original list. That way we're looping through one and changing the other:

solution.py
def disemvowel(word):
    vowels = ["a", "e", "i", "o", "u"]
    wordList = list(word)
    list_to_return = list(word)
    for letter in wordList:
        for vowel in vowels:
            if letter == vowel.upper() or letter == vowel.lower():
                list_to_return.remove(letter)
    word = ''.join(list_to_return )
    return word

Phew! That should do it. Let me know if anything doesn't make sense. As a bonus, here's a slightly cleaner way to check the vowels:

cleaner_solution.py
def disemvowel(word):
    vowels = ["a", "e", "i", "o", "u"]
    wordList = list(word)
    list_to_return = list(word)
    for letter in wordList:
        if letter.lower() in vowels:
            list_to_return.remove(letter)
    word = ''.join(list_to_return )
    return word

Cheers :beers:

-Greg

Spencer Hill
Spencer Hill
1,397 Points

Thanks a lot Greg! Didn't realise that was such a faux pas! Thanks also for clarifying how to use the .join() function properly.

Cheers for your time! This was a great, thorough explanation!

Greg Kaleka
Greg Kaleka
39,021 Points

Yeah, you have to be really careful because you'll end up with unexpected results as you skip elements of the list.

Happy to help! I always like debugging things like this :blush: