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

Since 'remove' removes the first instance of a value from a list, how do i go about removing the second instance of 'a' from the word 'Insatiable'.

Second, please add the try and except block, to say, 'No vowels were found in the word' if no vowels are present in the word.

disemvowel.py
def disemvowel(word):
    vowels = "aeiouAEIOU"
    my_list = list(word)
    for char in my_list:
        if char in vowels:
            my_list.remove(char)
    new_word = ''.join(my_list)
    print(new_word)


disemvowel("Insatiable")

6 Answers

William Li
PLUS
William Li
Courses Plus Student 26,868 Points

Since 'remove' removes the first instance of a value from a list, how do i go about removing the second instance of 'a' from the word 'Insatiable'.

It can remove the 2nd occurrence of 'a' by calling remove.('a') 2 times, that's not the problem here.

Generally speaking, it's a very bad idea to write a for loop to iterate through each element of a list while simultaneously shrinking the length of list by removing its items in the loop body.

Here's what happens in the first 2 iterations of your for loop in disemvowel("Insatiable")

  • in the 1st iteration, Check whether the first item in the list is a vowel.
  • "I" is a vowel, it's removed from the list
  • At the end of the 1st iteration, my_list becomes list("nsatiable").
  • now in the 2nd iteration of the loop, check whether the second item in the list is a vowel
  • "s" is not a vowel, therefore it's NOT removed.

You see the problem here? letter "n" was skipped and never get checked, that's because now with "I" removed, letter "n" is the 1st item in the list, and as far as the for loop is concerned, the first item on the list has been checked in the previous iteration, it doesn't care that the value of the 1st item has changed.

This is precisely why the second instance of "a" in the word doesn't get removed in your code. When there're 2 vowels back to back, the 2nd vowel will definitely be skipped checking after the removal of the 1st vowel. And the word you have here is Insatiable, the second occurance of "a" comes after letter "i", which happens to be a vowel also.

To avoid this problem, you can change your for loop into this

for char in word:

Now the code iterates through each letter in the String word, if a letter is found to be a vowel, it gets removed from my_list, problem solved.

Second, please add the try and except block, to say, 'No vowels were found in the word' if no vowels are present in the word.

I don't think that's necessary, the purpose of the disemvowel function is to strip away vowels, if any, from the argument; simply put, it's of no significance whether the word contains any vowels, we only need to make sure that the return value of this function is the same word w/ all possible occurrences of vowel removed.


PS:

I should also point out that, the grader is probably buggy, your code've passed the challenge, but it shouldn't have, as your implementation of disemvowel function has no return value.

From the challenge description

The function disemvowel takes a single word as a parameter and then returns that word at the end.

and the code template comes with 2 lines pre-written.

def disemvowel(word):
    return word

I do believe we should preserve these 2 lines and add more code in the middle to complete the implementation. Here's a slightly altered version of your disemvowel function definition.

def disemvowel(word):
    vowels = "aeiouAEIOU"
    my_list = list(word)
    for char in word:
        if char in vowels:
            my_list.remove(char)
    word = ''.join(my_list)
    return word

It'll pass the grader check, and more importantly, it complies with every requirement the challenge asks for.

Happy coding.

def disemvowel(word): return ''.join([c for c in word if not c.lower() in 'aeiou'])

I took a different turn to solve this...

def disemvowel(word):
    vowels = ['a','A','e', 'E', 'i', 'I', 'o', 'O', 'u', 'U']
    for vowel in vowels:
        word = word.replace(vowel, "")

    return word 
Arindam Roychowdhury
Arindam Roychowdhury
3,244 Points

This seems to work but doesn't pass.

def disemvowel(word):
    return ''.join(
        list(
            set(word) - set("aeiouAEIOU")
            )
        )

I just noticed the error: Hmm, got back letters I wasn't expecting! Called disemvowel('eNSWOZq') and expected 'NSWZq'. Got back 'WNSZq'

Clearly , its just an ordering issue. Which should not occur.

Hey can anyone explain to me whats going on with word = ''.join(my_list) i understand everything else but this bit thanks

you can read "".join(my_list) as take every item in my list and join them together, separated by an empty string.

ex. "---".join(["hello", "word", "python"]) will return "hello---world---python"

Check out the join method in the Python String Docs

Try removing the function call disemvowel("Insatiable").

The code challenge automatically calls and checks the function :)

Good luck! ~Alex

Hi Alex, i put the function call there to just give an example to my Question.My code actually works in the code challenge without the function call.