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

Could someone please tell me why this isn't working to disemvowel the word?

I've looked at other questions regarding this challenge and have seen other ways of completing it. I just don't see why my code isn't working too. The code seems to be removing some of the vowels but not all of them. There must be something that I'm missing and I just can't move on until I figure it out! Thanks :)

disemvowel.py
def disemvowel(word):
    list_of_word = list(word)
    vowels = ['a', 'e', 'i', 'o', 'u']
    for letter in list_of_word:
        if letter in vowels:
            list_of_word.remove(letter)
    new_word = ''.join(list_of_word)
    return new_word

4 Answers

You are changing the list while going from one index to the other, try using a copy of the list instead.

Thanks a lot for answering me! That's really good to know!

Hi Annie, there are 2 problems:

  1. Whenever you loop through a list and remove items from it, you get a mess. Ideally you iterate through a copy of the list and perform the removal on the original list. You can do that with either list_of_words.copy() or list_of_words[:]
  2. You are not taking into account the uppercase vowels.

Good luck.

Thanks so much for the reply Pedro! It makes sense now why it wasn't working. I appreciate the help!

Moosa Bonomali
Moosa Bonomali
6,297 Points
for letter in list_of_word:
        if letter in vowels:
            list_of_word.remove(letter)

The problem with your code has to do with the above lines. And in particular when you remove the letter from the list_of_word array.

Imagine you have the following word

s = "Hello"
a = list(s)

which you then convert to an array

a = ['H','e','l','l','o']

When you go through the array with a for loop. Lets look at what happens to the array indices.

a[0] = 'H'
a[1] = 'e'
a[2] = 'l'
a[3] = 'l'
a[4] ='o'

You can think of a pointer which points to the index 0, then 1, then 2, then 3, then 4. If you remove an element from the list, the pointer keeps going. Lets say our pointer was 2 and we remove the 1st 'l'.

a.remove('l')

The array will be now like this

a = ['H','e','l','o']

and the array indices are now as follows;

a[0] = 'H'
a[1] = 'e'
a[2] = 'l'
a[3] = 'o'

Our pointer is now 3. From the original array, we expect to be pointing to the 2nd 'l', but alas, because the array has changed and the pointer is 3, it will now be pointing to

a[3] = 'o'

which is now 'o'.

So essential by removing an element from the array, you are messing up the pointers and unintentionally skipping over some letters. To solve your problem, a possible solution is not to remove the letter, but replace it with a blank.

list_of_word[index] = ''

The 2nd thing is that the vowels may come in as capital letters and so you need to change their case to lower when comparing with your vowel list;

if letter.lower() in vowels:

After all that here is your code, with the changes made

def disemvowel(word):
    list_of_word = list(word)
    vowels = ['a', 'e', 'i', 'o', 'u']
    for index,letter in enumerate(list_of_word):
        if letter.lower() in vowels:
            list_of_word[index]=""
    new_word = ''.join(list_of_word)
    return new_word

word  = disemvowel("LHEpFeUd")
print(word)

Thanks so much for the reply Moosa! Great explanation of the concept, it really makes sense to me now!

Strings are iterable too :)

and

maybe some of the vowels are upper cased

You can use pythons str.lower() -> letter.lower()

This was my attempt with sort of your own code. :dizzy: :dizzy: :dizzy: :dizzy:

def disemvowel(word):
    vowels = ['a', 'e', 'i', 'o', 'u']
    list_of_word = []
    for letter in word:
        if letter.lower() not in vowels:
            list_of_word.append(letter)
    new_word = ''.join(list_of_word)
    return new_word

Thanks so much for replying! I tried looping through the string at first but then realized I couldn't remove a letter from the string, so I wasn't sure where to go from there and I tried the list instead. But I really like your way, thanks a lot for the tip!!

Moosa Bonomali
Moosa Bonomali
6,297 Points

If you wanted to loop over the string, you could have just created a new string and you add to the new string the letters which are not vowels;

def disemvowel(word):
    new_word = ""
    vowels = "aeiou"
    for letter in word:
        if not letter.lower() in vowels:
            new_word += letter
    return new_word

Oh cool! I see how that works. Thanks again Moosa!