Anti_vowel code- how to fix this?


#1

I'm doing the anti_vowel exercise and while I have looked up working answers, I want to see if I can get my original attempt at this code to work.

I'm puzzled because I seem to have gotten it to work but it fails on the last "o" in "Words". It seems to have reached a limit on how many vowels it can remove using the if statement and I would like to know why.

Is there a way to get this version of the solution to work? Thank you.

def anti_vowel(text):
    text_list = list(text)
    for x in text_list:
        if x in "aeiou":
            text_list.remove(x)
    return "".join(text_list)

print anti_vowel("Hey look Words!")


#2

.remove() causes a shift of elements. That is something that needs to be accounted for.


#3

I don't really understand. Why does that stop the loop from iterating through each item in the list and checking if x is in "aeiou"? What do I need to add/change to make it work?


#4

>>> def anti_vowel(text):
    text_list = list(text)
    for x in text_list:
        print (x, text_list)
        if x in "aeiou":
            text_list.remove(x)
    return "".join(text_list)

>>> print (anti_vowel("Hey look Words!"))
H ['H', 'e', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
e ['H', 'e', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
  ['H', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
l ['H', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
o ['H', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
k ['H', 'y', ' ', 'l', 'o', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
  ['H', 'y', ' ', 'l', 'o', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
W ['H', 'y', ' ', 'l', 'o', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
o ['H', 'y', ' ', 'l', 'o', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
d ['H', 'y', ' ', 'l', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
s ['H', 'y', ' ', 'l', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
! ['H', 'y', ' ', 'l', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
Hy lk Words!
>>>

Study this closely.

Explanation of evidence.

When the first 'o' in 'look' is removed, the list shifts all elements to the right, one space to the left to fill the void. The iterator jumps to the next element, a 'k', skipping the next 'o'.

When the 'o' is encountered in 'Words', the .remove() method takes out the first 'o' it finds in the list, the one that was skipped over, earlier.

More to the point...

>>> print (anti_vowel("aeiouaeiouaeiou"))
a ['a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
i ['e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
u ['e', 'o', 'u', 'a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
e ['e', 'o', 'a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
o ['o', 'a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
a ['a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
i ['e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
u ['e', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
eoaeiou
>>>

Consider...

>>> def anti_vowel(text):
    text_list = list(text)
    for x in text:
        print (x, text_list)
        if x in "aeiou":
            text_list.remove(x)
    return "".join(text_list)

>>> print (anti_vowel("aeiouaeiouaeiou"))
a ['a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
e ['e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
i ['i', 'o', 'u', 'a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
o ['o', 'u', 'a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
u ['u', 'a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
a ['a', 'e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
e ['e', 'i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
i ['i', 'o', 'u', 'a', 'e', 'i', 'o', 'u']
o ['o', 'u', 'a', 'e', 'i', 'o', 'u']
u ['u', 'a', 'e', 'i', 'o', 'u']
a ['a', 'e', 'i', 'o', 'u']
e ['e', 'i', 'o', 'u']
i ['i', 'o', 'u']
o ['o', 'u']
u ['u']

>>>

In the above we iterate the string, and modify the list copy. That way our loop doesn't skip any characters in the string.


#5

Thank you, that was very thorough and I understand what you mean now. I figured it was something like that but didn't understand the mechanics behind why it skipped it.

I appreciate your time.

EDIT: I tried it and got this error:

"Oops, try again. Your function fails on anti_vowel("Yab Gab to Trab Yab Yab Aeiouz"). It returns "Yb Gb t Trb Yb Yb Az" when it should return "Yb Gb t Trb Yb Yb z".

Either way, thanks for explaining what the problem was, huge help.


#6
if x.lower() in "aeiou":

#7

Ah OK thank you, it works just fine now


#9

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.