8. Anti-Vowel - What is happening with my code?


#1

I have no idea what is wrong with my code. I have spent hours trying to fix and I got to better results, but never perfect. I just have no idea what I can do to fix it.
This is my code:

vowels = ["A", "E", "I", "O", "U", "a", "e", "i", "o", "u"]
def anti_vowel(text):
words = list(text)
for letter in words:
if letter in vowels:
words.remove(letter)
return ''.join(words)

print anti_vowel("AEIOUaeiou")

Calling it with AEIOUaeiou returns "EOaiu" and calling it with "Hey look Words!" returns "Hy lk Words!"


#2

Hi sircommoner,

I was wondering the same thing, as the code made sense from what I could see. But it looks like this has to do with a strange behavior in Python when you iterate over a list and remove items.:

From the Python Documentation (Python Documentation)

"It is not safe to modify the sequence being iterated over in the
loop (this can only happen for mutable sequence types, such as lists). If you need to modify the list you are iterating over (for example, to duplicate selected items) you must iterate over a copy."

But if you change your code as below, making a copy of the list (" for letter in words [ : ] "), I think it works as we'd expect ---

vowels = ["A", "E", "I", "O", "U", "a", "e", "i", "o", "u"]
def anti_vowel(text):
    words = list(text)
    for letter in words[:]:
        if letter in vowels:
            words.remove(letter)
    return ''.join(words)

print anti_vowel("AEIOUaeiou")

Good luck!

.


#3

Ok i have run this i don't know how many ways. The string is output correctly to the screen but the lesson says i fail is it maybe a glitch?

Here is my code.

# vowel List
vowel = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
# Fuction to remove vowels
def anti_vowel(text):
    words = list(text)
    # Loop to move through the letters in TEXT
    for i in words:
        if i in vowel:
            words.remove(i)
    return ''.join(words)
print(anti_vowel(words))

#4

Oh, thanks for the explanation! I wrote a code that, instead of removing the vowels from the string, makes another string without the vowels.


#5

so my problem was the two brackets and the additional colon, just exactly what does that do?

> for i in letters[:]:


#6

the only thing i dont understand here is ** words[:]** why not just words. can you explain pls? thanks


#7

Oh yeah, my explanation was a little rushed / unclear.

Based on the documentation, when you have a list named words and you try to iterate through each element and delete elements along the way, in Python, at least, it doesn't work as you would expect.

But if you iterate through list words[:], it's the same as creating a copy of words and going through all of its elements ("[:]" is like words[0:-1]; it means "from the first to the last element in words").

I don't understand why it works, honestly; it's just a way around this weird Python behavior.


#8
def anti_vowel(text):
    vowel = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
    res=[]
    for i in text:
        if i not in vowel:
            res.append(i)
    return ''.join(res)
print(anti_vowel('Hey You!'))

Here's another solution that works.


#9

Yes, I think micoo's version is more "Pythonic", and a more typical solution to such problems - probably in part due to the iteration issue we've been seeing.


#10

This was my code, and it worked.

def anti_vowel(text):
avowel=[]
for i in text:
if i not in "aeiouAEIOU":
avowel.append(i)
return ''.join(avowel)
print avowel

print(anti_vowel('How would you like to see me?'))`


#11

Thanks @micoo for sharing the code. Don`t mind but can you please explain this code briefly.


#12

@systemized
Sure its not a problem.
First I create a list containing all the vowels.
Then with the " for i in text " we go through the text letter by letter.
With the " if i not in vowel "I check if the letter for example "b" is not in the vowel list.
If it's not with " res.append(i) " I put it in the result list,which will contain all the letters except the vowels.
And in the end I just return the resulting list.

PS: I'm sorry for the late response.