8/15 I am so stupid . Do I have a faster way to solve this? thank u!


#1

def anti_vowel(text):

#for x in text:
text=text.replace("a","")
text=text.replace("e","")
text=text.replace("i","")
text=text.replace("o","")
text=text.replace("u","")
text=text.replace("A","")
text=text.replace("E","")
text=text.replace("I","")
text=text.replace("O","")
text=text.replace("U","")

print text
return text
#return text

anti_vowel("Hey You!")


#2

Nothing stupid about a piece of code that gives the solution! But quite right to see if there are more efficient ways.

One solution is using the for loop you started to try and commented out:

def anti_vowel(text):
    out = ""
    for x in text:
        if x in "aeiouAEIOU":
            x = ""
        out += x
    return out

print anti_vowel("Hey You!")

for x in text: will loop through each character treating text as an array of characters, if in "aeiouAEIOU" will check for vowel and case - you could also use x.lower() to change case before checking and that way capture capitals, the variable out has the characters added with "" substituting.

Another way is for when you learn about regular expressions!

import re

def anti_vowel_regex(text):
    return re.sub(r'[aeiouAEIOU]', "", text)
    

print anti_vowel_regex("Hey You!")

import re imports the regular expression module, re.sub uses a regular expression to match characters, replaces with "", taking text as its input, and job done.

Keep up the learning, try and get the for loop working, it's an important part to learn.


#3

Thank u so much ! you re the master of python !


#4

Thank you finally understood for loops better.


#5

Your first suggestion has a quadratic time complexity!
It requires on the order of 10^12 operations when it should only need 10^6 for a string of a million consonants.

Here's an input that the function should handle in at most a couple of seconds:

 anti_vowel(''.join(['z'] * 1000000))

What will take time is your "adding" of characters to strings. You can't add anything to a string because strings are immutable, can't be changed. Instead what happens is that each time you "add" another character, a whole new string is created, which is going to take time relative to its length.

What you can do instead is append the characters to a list and then create a string from that list once there aren't going to be any more changes.


#6

So first suggestion will create lots of "out" ? and it needs lots of time? :persevere:


#7

It turns out, that it actually works just fine in CPython (the de facto standard Python implementation), because apparently there's a performance hack there where they actually change the string even though strings are supposed to be immutable. They can do that because Python recognizes that there is nothing that depends on that string not changing.

But I also tried running it in Jython and in PyPy, and that performance hack isn't present in either of those.

I'd rather assume that strings really are immutable, even when they don't need to be, and do it in some way that is guaranteed to always work the way I want.

Still, it's cool that CPython does that, I had no idea that it did.


#8

I benefited from this explanation too, thanks a lot! :smile:


#9

Thanks for the information!

def anti_vowel(text):
    out = []
    for x in text:
        if x in "aeiouAEIOU":
            x = ""
        out.append(x)
    return "".join(out)

Would that be okay?

I'd imagine it'd be hard to perform better than it's built in regex substitute?