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

Help with disemvowel function!!

Confused why this works on my console but not in the challenge

disemvowel.py
def disemvowel(word):
    word_list = list(word)
    for vowel in word_list:
        if vowel.upper() == "A" or vowel.upper() == "E" or vowel.upper() == "I" or vowel.upper() == "O" or vowel.upper() == "U":
            word_list.remove(vowel)
        else:
            continue  
    return ''.join(word_list)

5 Answers

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,428 Points

The error is caused by manipulating the same list that is used in defining the for loop. When the .remove() is executed, it causes the pointers controlling the for loop to be off with each deletion. A quick fix is to have the for loop operate on a temp copy of word_list By adding slice notation :

    for vowel in word_list[:]:
Umesh Ravji
Umesh Ravji
42,386 Points

Hi David, what strings did you use to test the function on? Removing items in a list, while iterating over it isn't as straightforward as you would think. Also, you have to check for lowercase vowels too.

print(disemvowel('BANANAS'))  # BNNS
print(disemvowel('AEIOU'))  # EO

Checking for membership in a list is much more easier than to have 10 conditional checks. You may iterate over the list in reverse if you want to keep using the remove method.

def disemvowel(word):
    vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
    word_list = list(word)
    for vowel in reversed(word_list):
        if vowel in vowels:
            word_list.remove(vowel)
    return ''.join(word_list)

However, its probably better to use the strategy outlined by Jason in his comment, just below the answer here. https://teamtreehouse.com/community/can-you-explain-me-what-i-am-doing-wrong

When i add " for vowel in reversed(word_list):" everything works.

Why does reversed fix the problem? It seems as if before when I had 2 consecutive vowels that was the problem. However even if you reverse the word "GREAT" there are two vowels back to back so shouldnt the problem occur again?

Chris Freeman
Chris Freeman
Treehouse Moderator 68,428 Points

The reversed() creates a new list so the remove isn't affecting the for loop. Using reversed() for the side effect of creating a copy is misleading code. If a copy is needed, it is pythonic to use slice [:] notation

Umesh Ravji
Umesh Ravji
42,386 Points

Hi Chris Freeman , please correct me if I am wrong, but my understanding is that reversed() returns an iterator and not a copy of the list.

nums = [1, 2, 3, 4, 5]
iter = reversed(nums)
nums[-1] = 42
while True:
    try:
        print(next(iter))
    except StopIteration:
        break

42
4
3
2
1
Chris Freeman
Chris Freeman
Treehouse Moderator 68,428 Points

Correct. reverse returns an iterator. When run to completion it effectively creates a copy of the list, but one item at a time as needed. So in terms of compute process size it will be smaller than a slice copy but not necessarily faster.

My suggestion was that if performance is similar it's best to go with the more readable version using the Python idiom of a slice copy [:]

Opanin Akuffo
Opanin Akuffo
4,713 Points

How come this doesn't work in challenge but works on workspaces. I don't see anything wrong with code. Please help.

def disemvowel(word):
  vowels = ['a', 'e', 'i', 'o', 'u']
  guy = list(word.lower())
  for vowel in guy[:]:
    if vowel in vowels:
      guy.remove(vowel)
  return ("".join(guy))
Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 68,428 Points

Any uppercase consonants are being lowercased with the vowels. Try to use lower only on the compare or don't use lower and simply add uppercase vowels to your vowels list.