Correct code to remove the vowels from a string in Python

I'm pretty sure my code is correct but it doesn't seem to returning the expected output:

input anti_vowel("Hey look words") --> outputs: "Hey lk wrds".

Apparently it's not working on the 'e', can anyone explain why?

def anti_vowel(c):
    newstr = ""
    vowels = ('a', 'e', 'i', 'o', 'u')
    for x in c.lower():
        if x in vowels:
            newstr = c.replace(x, "")        
    return newstr

Solution 1:

The function str.replace(old, new[, max]) don't changes c string itself (wrt to c you calls) just returns a new string which the occurrences of old have been replaced with new. So newstr just contains a string replaced by last vowel in c string that is the o and hence you are getting "Hey lk wrds" that is same as "Hey look words".replace('o', '').

I think you can simply write anti_vowel(c) as:

''.join([l for l in c if l not in vowels]);

What I am doing is iterating over string and if a letter is not a vowel then only include it into list(filters). After filtering I join back list as a string.

Solution 2:

Why don't you do it with regexp? According to the documentation, something like this should work:

import re

def anti_vowel(s):
    result = re.sub(r'[AEIOU]', '', s, flags=re.IGNORECASE)
    return result

If you're using the function often, you could compile the regexp and use the compiled version.

Solution 3:

Try String.translate.

>>> "Hey look words".translate(None, 'aeiouAEIOU')
'Hy lk wrds'

string.translate(s, table[, deletechars])

Delete all characters from s that are in deletechars (if present), and then translate the characters using table, which must be a 256-character string giving the translation for each character value, indexed by its ordinal. If table is None, then only the character deletion step is performed.

https://docs.python.org/2/library/string.html#string.Template.substitute

Or if you're using the newfangled Python 3:

>>> table = str.maketrans(dict.fromkeys('aeiouAEIOU'))
>>> "Hey look words.translate(table)
'Hy lk wrds'

Solution 4:

Another option is to forego the vowel variable and put the char's to remove in the loop.

    def anti_vowel(text):
        for i in "aeiouAEIOU":
            text = text.replace(i,"")
        return text

    print anti_vowel("HappIEAOy")

Solution 5:

You should do this:

initialize newstr to c, and then

for x in c.lower():
    if x in vowels:
        newstr = newstr.replace(x, "")

That's because str.replace(old, new[, max]) returns the a copy of the string after replacing the characters:

The method replace() returns a copy of the string in which the occurrences of old have been replaced with new, optionally restricting the number of replacements to max.

So, this is the correct code:

def anti_vowel(c):
    newstr = c
    vowels = ('a', 'e', 'i', 'o', 'u')
    for x in c.lower():
        if x in vowels:
            newstr = newstr.replace(x,"")

    return newstr

You can also do it in a more pythonic way:

''.join([x for x in c if x not in vowels])