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

Disemvowel

This seems to be working on my end. What is wrong with it? What test case is it still failing?

disemvowel.py
def is_vowel(letter):
    vowels = ['a','A','e','E','i','I','o','O','u','U']
    if letter in vowels:
        return True
    else:
        return False

def list_to_word(word):
    word_string = ''
    for letter in word:
        word_string += letter
    return word_string

def disemvowel(word):
    word = list(word)
    for letter in word:
        if is_vowel(letter):
            word.remove(letter)
    word = list_to_word(word)
    return word

For example: disemvowel('banana') gives: bnn

4 Answers

Hi Arjun,

Your code is going to fail any test case that has consecutive vowels.

The problem is in the following loop:

for letter in word:
        if is_vowel(letter):
            word.remove(letter)

Modifying an iterable while you're looping over it can lead to problems. In this case, you're removing letters from word while looping over it.

When a letter is removed, the remaining letters all move down one spot to occupy the empty spot. So you end up skipping over the letter that comes after the one you just removed. If that's a vowel, then you'll miss it.

To fix this, you can iterate over a copy and make modifications to the original. Slice notation can be used to make a copy of word

for letter in word[:]:

Your code should pass after that change.

However, as others have pointed out, the code can be much simpler and shorter than that.

Wow. I didn't anticipate so many replies! I am overwhelmed.

Thank you Jason. It makes so much sense now! I completely forgot that .remove() modifies the list. I guess I learnt the hard way why iterating over a slice copy is such an important pattern in python!

I don't think the challenge expects you to add additional functions.

Don't worry; your code looks fantastic but the code challenge just seems picky.

You might have to combine some stuff into the disemvowel function.

Also, I just want to note that you don't need to make any lists here, since you can just make a string and concatenate letters on that. This is shown below :smile:

Try this:

def disemvowel(word):
    result = ''
    for letter in word:
        if letter.lower() not in 'aeiou':
            result += letter
    return result

P.S.: In case you're curious, I have another interesting answer about something about this :)

I hope this helps :smile:

Good luck! ~Alex

That is so much simpler! It worked.

You are really overcomplicating the solution.

  1. You don't need is_vowel(). Just compare against a constant container or string within the disemvowel() function (maybe using the in operator).
  2. You also don't need the list_to_word() function at all. Just return a new variable from your disemvowel() function instead of relying on another function.
  3. (EDIT - See the comments on this post. This point isn't entirely correcty. Check Jason Anello's answer.) Lastly, your current disemvowel() function isn't removing uppercase letters. You can use the .upper() or .lower() methods for this. In this way, you can also catch all vowels without the need to store both upper and lowercase letters in your vowels variable.

Actually, his program does remove uppercase and lowercase vowels :)

No. It doesn't.

http://imgbox.com/k9beDaZl

The program does remove uppercase vowels. You can see in the vowels list that both upper and lower case vowels are listed.

Try testing it with "bAnAnA"

The problem with the program is that it doesn't remove every second vowel when there are consecutive vowels.

In your 3rd test case, every second vowel is an uppercase one, which makes it look like it doesn't remove uppercase vowels.

That's an interesting error. Thanks for clearing that up.

Yeah, it could be tricky to catch without the right test cases.

If you had tested with "AaEeIiOoUu" then it would have looked like it wasn't removing lowercase vowels :)

Rafal MAjewski
Rafal MAjewski
1,587 Points
def disemvowel(word):
    a=[]
    word=word.lower()
    litery=["a", "e", "i", "o", "u"]
    for letter in word:
        if letter not in litery:
            a.append(letter)
    b=''.join(a)
    print(b)

fixed code formatting

See this link for how to post code: https://teamtreehouse.com/forum/posting-code-to-the-forum

You have a few issues with your code. You have to return the word. Also, you're lowercasing the entire word that comes in which means you're not maintaining original letter casing.