-1

I've entered the following code to remove vowels, but it doesn't work specially for repetitive letters! just run my code to understand the problem!

def anti_vowel(text):

    text=list(text)

    for i in text:

        if i=='e' or i=='E' or i=='a' or i=='O' or i=='o' or \

        i=='A' or i=='u' or i=='U' or i=='i' or i=='I':

        text.remove(i)

text1=''.join(text)

text2=str(text1)

return text  

print anti_vowel("Hey Look World!")

I searched internet and find the answer to change my code to:

for i in text[:]:

tell me what's happening?

Akram
  • 11
  • 1

1 Answers1

2

As the documentation clearly says, list.remove will:

remove first occurrence of value

So of course it doesn't remove all occurrences of the value. That's like complaining that a function called print prints the values instead of multiplying them by 3.

If you want to remove all occurrences of a value, there are many ways you could do that. For example, you could call remove in a loop until it raises a ValueError.


But there are much bigger problems with your code.

First, you're not allowed to delete things from a list while iterating over it. This will cause all kinds of bad things—most commonly, it will cause the iteration to skip over many values. You can often solve this by iterating backward, but that won't work when you're using functions like remove that inherently work from the front. You can almost always solve this by iterating over a copy of the list (that's what your for i in text[:]: does; text[:] is a copy of a slice of the entire list).

Second, you're duplicating your work. Why manually find every 'e' just to call remove so it can search from the beginning for the first e? Either get rid of the outer loop and just call remove until you're done, or get rid of the remove and just use del to remove the value you've already done the hard work of searching for—or, best of all, reorganize your code so you can just do it all in order.

So, three and a half options:


for vowel in 'AEIOUaeiou':
    while True:
        try:
            text.remove(vowel)
        except ValueError:
            break

for i, letter in reversed(enumerate(text)):
    if letter in 'AEIOUaeiou':
        del text[i]

for i, letter in enumerate(text[:]):
    if letter in 'AEIOUaeiou':
        del text[i]

text = [letter for letter in text if letter not in 'AEIOUaeiou']

Or, as Matthias points out, a regular expression might be a better answer in this case; the only problem is that you have to convert your list into a string to run re.sub on it, then convert it back to a list afterward… but that's really easy:

text = list(re.sub(r'[aeiou]', '', ''.join(text), flags=re.IGNORECASE))
abarnert
  • 313,628
  • 35
  • 508
  • 596