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

Error code: X not in list

Here is my approach to writing disemvowel.

When testing this function against something like "banana", I get the error code:

x is not on the list. NOTE that this is NOT my complete solution, but just a test case to get the solution going. X is not even on the Vowel list ... so where is it getting that value from?!

disemvowel.py
vowels = ['a','e','i','o','u']


def disemvowel(word):
    wordlist = list(word)
    for vowel in vowels:
        wordlist.remove(vowel)
        print(wordlist)
    return word

disemvowel("banana")

7 Answers

james south
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
james south
Front End Web Development Techdegree Graduate 33,271 Points

when you put remove(vowel), the first vowel is of course 'a', and remove does what it says, removes the first occurrence of 'a' in the list. then it moves on to 'e', finds no e's and stops cause it throws an error. when you put remove('a') it is actually doing the same thing, except because you are looping, it is calling remove('a') as many times as there are items in the list (5). if that number (5) exceeds the number of a's in the word (3), it will remove them all. so a word like banana that has 3 a's is having them all taken out, 1 at a time, because there are 5 vowels. when vowel is 'a', it takes out the first 'a', then when vowel is 'e', it takes out the next 'a', then when vowel is 'i', it takes out the next 'a', etc. run the code on banananananananana and there will be a's left when it finishes.

Based on your feedback, I have made the following changes:

vowels = ['a','e','i','o','u']


def disemvowel(word):
    word = word.lower()
    wordlist = list(word)
    for letter in wordlist:
        for vowel in vowels:
            try:
                wordlist.remove(vowel)

            except ValueError:
                pass
    print(wordlist)
    word = ''.join(wordlist)
    return word

It seems to be giving me the right solution, but the challenge I'm trying to solve isn't taking it

Why are you returning word? It hasn't been modified in your function.

I'm just testing the function using the print(wordlist) statement. I'll be converting the wordlist into a string of words...but I'm not understanding the error message!

james south
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
james south
Front End Web Development Techdegree Graduate 33,271 Points

the error is ValueError: list.remove(x): x not in list. you are calling remove on vowels that are not in your word, and the remove method throws an error if the value is not found. if you used a conditional statement for instance to test if a word had a certain letter before removing, that would be a way to prevent this error.

Darn it I was about to say that :laughing:

Upvoted :+1:

ok so I fixed the ValueError using a try/except block

def disemvowel(word):
    wordlist = list(word)
    try:
        for vowel in vowels:
            wordlist.remove(vowel)
            print(wordlist)
    except:
        pass

disemvowel("banana")

so now I get no value error, but the function only removes the first occurrence "a" of "banana", and ignores the rest. And if I pass it something like "cherry", it detects no vowels. Oddly enough, if I pass the string directly into the remove function (wordlist.remove('a')), it actually removes all occurrences of "a" in "banana"

Don't do the try/except stuff on the entire loop. If an error occurs in the try block, it will actually stop the code in the block, and it will move onto the except (unless the except is catching a different error). It won't first jump into the except block then continue running the try block.

Do the try on only this line:

wordlist.remove(vowel)
vowels = ['a','e','i','o','u']


def disemvowel(word):
    wordlist = list(word)
    for vowel in vowels:
        try:
            wordlist.remove(vowel)
        except ValueError:
            pass
    print(wordlist)


disemvowel("banana")

That still just removes the first occurrence. not sure where I'm going wrong

james south
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
james south
Front End Web Development Techdegree Graduate 33,271 Points

from the docs for the remove method: s.remove(x) remove the first item from s where s[i] == x Note: remove raises ValueError when x is not found in s

That's so odd because when I pass an atual string into remove, for ex remove('a'), it gets all occurrences.

james south
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
james south
Front End Web Development Techdegree Graduate 33,271 Points

run it on the word "beaeeetyeeeu", a fake word i just made up for testing purposes. your code lets some of the vowels through. you are modifying a list that you are looping through, which is resulting in skipped elements. when remove removes an element, it shifts the remaining elements to the left, but the loop moves on, so elements get skipped. to fix make a copy of the list and loop through that and modify the original, or vice versa.

Here is another solution. I feel like I'm getting closer with this one. However, it seems like towards the end I get duplicate letters in my final word, and can't seem to filter them out to get my final answer.

vowels = ['a','e','i','o','u']


def disemvowel(word):
    word = word.lower()
    wordlist = list(word)
    wordlistcopy = []
    for vowel in vowels:
        for letter in wordlist:
            if vowel not in letter:
                wordlistcopy.append(letter)
                print(letter)



    print(wordlistcopy)
    word = ''.join(wordlistcopy)
    print(word)
    return word


disemvowel("word")
james south
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
james south
Front End Web Development Techdegree Graduate 33,271 Points

this code makes the original word much longer. your copy isn't a copy, it's an empty list. to make a copy would be like myCopy = myOriginal[:]. but that doesn't make a difference for this code, it multiplies the original word either way. this code you posted above earlier:

def disemvowel(word):
    word = word.lower()
    wordlist = list(word)
    for letter in wordlist:
        for vowel in vowels:
            try:
                wordlist.remove(vowel)

            except ValueError:
                pass
    print(wordlist)
    word = ''.join(wordlist)
    return word

works if you loop through a copy of wordlist and modify the original.

Here is my modified code now. It passes every test case I put into it (something with caps vowels mixed with lower case), even "beaeeetyeeeu" the word you made up for testing purposes. But when I try to complete the challenge, it's still not taking it :( it says "Hmm, got letters back I wasn't expecting"

vowels = ['a','e','i','o','u']

def disemvowel(word):
    word = word.lower()
    wordlist = list(word) #converting string into list
    wordlistcopy = wordlist[:] #copy of my original list

    for letter in wordlist:
        for vowel in vowels:
            try:
                wordlistcopy.remove(vowel) #removing from copy while looping through original 
            except ValueError:
                pass


    word = ''.join(wordlistcopy) #convert list back into string
    print(word)
    return word
Tom Miller
Tom Miller
2,640 Points

In your first step, you are lowercasing the entire word, including any capital consonants, which is not what the challenge wants you to do. Use the .lower() method later on, so that you are only checking for and removing the lowercase and uppercase vowels, whilst leaving the consonants exactly as they were.