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

My function is only removing the first vowel. I'm using a for in so why is it not performing this on each step?

def disemvowel(word): word = list(word) for i in word: if i == "a": word.remove(i) elif i == "e": word.remove(i) elif i == "i": word.remove(i) elif i == "o": word.remove(i) elif i == "u": word.remove(i) elif i == "A": word.remove(i) elif i == "E": word.remove(i) elif i == "O": word.remove(i) elif i == "I": word.remove(i) elif i == "U": word.remove(i) return word

What's missing?

disemvowel.py
def disemvowel(word):
    word = list(word)
    for i in word:
        if i == "a":
            word.remove(i)
        elif i == "e":
            word.remove(i)
        elif i == "i":
            word.remove(i)
        elif i == "o":
            word.remove(i)
        elif i == "u":
            word.remove(i)
        elif i == "A":
            word.remove(i)
        elif i == "E":
            word.remove(i)
        elif i == "O":
            word.remove(i)
        elif i == "I":
            word.remove(i)
        elif i == "U":
            word.remove(i)
    return word
    word = "".join(word)

2 Answers

Alex Koumparos
seal-mask
.a{fill-rule:evenodd;}techdegree
Alex Koumparos
Python Development Techdegree Student 36,887 Points

Hi Megan,

You have a couple of issues that are preventing your function from working as you expect.

First, your for-in loop. You are iterating through your list and removing items from it. This can cause the interpreter to skip items. Let's look at a simple example to see why this is so.

Imagine you have passed the word "hoop" into your function. The function iterates through, so on iteration number 0, the function sees 'h', it's not a vowel, so it continues (and your list is still ['h','o','o','p']. On iteration number 1, it sees 'o', a vowel, so it removes it. The list is now '['h','o','p']`. It now moves to position number 2, which is 'p'. It's not a vowel, so the function doesn't change anything, and now the function is finished. The second 'o' never got removed because the loop never saw it (it became index 1 after the loop had finished with index position 1).

There are a number of ways you can rewrite your function so that you are not modifying a list as you iterate through it. For example, you could compute the length of your word and then iterate through a range of that length, accessing the value at that index each time round. Or, you could iterate through word but instead of changing word, you could build up a new string in a different variable and then return that.

If you're still stuck after tweaking your approach, let me know and I'll give you some more pointers.

Your second critical issue is that you are returning word (a list) before converting it back to a string. Since return ends execution of the function, the join never gets executed. Even if it was executed, the list is what is actually being given back to the challenge evaluator and it is looking for a string. This is a simple fix as all you need to do is switch the last two lines around.

Hope that helps

Cheers

Alex

Thanks so much!

Because you're trying to remove from a list while iterating over that list. In other words, if you've 'cei', and you remove the e, then you've got 'ci' left. However, you're at position 1 in the iterator, so the iterator tries to move to position 2 - where this no letter now, ending the loop.

So you can either do some internet sleuthing to see how to solve this type of problem or you can rewrite the loop to add only the consonants to a list and returning the string of that list. (Incidentally, your join comes after your return, so you won't return a string in your current implementation)

Thanks so much!