This question already has answers here:
Correct code to remove the vowels from a string in Python
(13 answers)
Closed 4 years ago.
I'm beginning to learn Python and I'm trying to create a function that removes vowels from a given string.
This is my Code :
def anti_vowel(text):
li = []
for l in text:
li.append(l)
while 'a' in li:
li.remove('a')
while 'A' in li:
li.remove('A')
while 'A' in li:
li.remove('e')
while 'e' in li:
li.remove('E')
while 'E' in li:
li.remove('i')
while 'i' in li:
li.remove('I')
while 'I' in li:
li.remove('o')
while 'o' in li:
li.remove('O')
while 'u' in li:
li.remove('u')
while 'U' in li:
li.remove('U')
return "".join(li)
I get the "list.remove(x): x not in list" error when I try to run it.
I know this error's been already asked about here but I didn't really get the answers in those specific cases.
thanks for reading and please help :)
def anti_vowel(text):
li = ''
for l in text:
if l.lower() not in 'aeiou':
li+=l
return li
You are overcomplicating it, just use a generator expresion:
def anti_vowel(text):
return "".join(x for x in text if x not in "AEIOUaeiou")
>>> anti_vowel("asldkfoihyoihbiw")
'sldkfhyhbw'
You can use loops also:
def anti_vowel(text):
li = []
for l in text:
if l not in "AEIOUaeiou":
li.append(li)
return "".join(li)
You have some mis-matches in your while statement, for example:
while 'e' in li:
li.remove('E')
If there is no 'E' but there is an 'e' this will cause a problem.
You either need to go through and make sure they are consistent.
Or you could write a small function to deal with each vowel:
def remove(letters, vowel):
while vowel in letters:
letters.remove(vowel)
You can then call this for each vowel.
def anti_vowel(text):
li = []
for l in text:
li.append(l)
for vowel in ['a', 'A', 'e', 'E', 'i', 'I', 'o', 'O', 'u', 'U']:
remove(li, vowel)
return "".join(li)
A more Pythonic way would be to pull out the required letters, using a list comprehension or generator, as per the answer from Netware. I'm just pointing out the source of your error.
If you catch yourself repeating something lots, and copy/pasting then tweaking, you can easily miss a few places that need tweaking.
Try to change the repeats into a function.
Related
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
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.
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.
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'
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")
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])
vowels = ('a', 'e', 'i', 'o', 'u', 'A', 'I', 'E', 'O', 'U')
for char in text:
if char in vowels:
text = text.replace(char, '')
return text
One more simpler way can be extracting the non-vowel characters from string and returning them.
def anti_vowel(text):
newstring=""
for i in text:
if i not in "aeiouAEIOU":
newstring=newstring+i
text=newstring
return text
I know there are many correct solutions on this subject but I thought to add few fun ways of solving this problem.
If you come from a C++/C# or Java, you will tend to use something like compare then action using the index to remove the unwanted entry in a for loop. Python has the Remove and Del functions. Remove function uses the value and
del uses the index.The pythonic solution is in the last function. Lets see how we can do that:
Here we are using the index in a for loop and del function very similar in C++:
def remove_vol(str1):
#list2 = list1 # this won't work bc list1 is the same as list2 meaning same container#
list1 = list(str1)
list2 = list(str1)
for i in range(len(list1)):
if list1[i] in volwes:
vol = list1[i]
x = list2.index(vol)
del list2[x]
print(list2)
Using the remove function:
def remove_vol(str1):
list1 = list(str1)
list2 = list(str1)
for i in list1:
if i in volwes:
list2.remove(i)
print(list2)
Building new string that does not contain the unwanted chars using their indexes:
def remove_vol(str1):
list1 = list(str1)
clean_str = ''
for i in range(len(list1)):
if list1[i] not in volwes:
clean_str += ''.join(list1[i])
print(clean_str)
Same as in the solution in above but using the value:
def remove_vol(str1):
list1 = list(str1)
clean_str = ''
for i in list1:
if i not in volwes:
clean_str += ''.join(i)
print(clean_str)
How you should do it in python? Using list comprehension! It is beautiful:
def remove_vol(list1):
clean_str = ''.join([x for x in list1 if x.lower() not in volwes])
print(clean_str)
def anti_vowel(text):
new=[]
vowels = ("aeiouAEIOU")
for i in text:
if i not in vowels:
new.append(i)
return ''.join(new)
i hope this helps..
def anti_vowel(text):
new_text = ""
for i in text:
if i == 'a' or i == 'A':
pass
elif i == 'e' or i == 'E':
pass
elif i == 'I' or i == 'i':
pass
elif i == 'o' or i == 'O':
pass
elif i == 'u' or i == 'U':
pass
else:
new_text = new_text + i
return new_text
print anti_vowel('Hey look Words!')
My implementation:
# Ask the user for input:
user_input = input("enter a string with some vowels: ")
print("input string: " + str(user_input))
vowels = ('a','e','i','o','u','A','E','I','O','U')
new_string="";
for i in range(0,len(user_input),1):
if user_input[i] in vowels:
print ('found a vowel, removing...')
else:
new_string+=user_input[i]
print("I've removed the vowels for you. You're welcome! The new string is: " + new_string)
A fairly simple approach could be;
def anti_vowel(text):
t = ''
for c in text:
if c in "aeiouAEIOU":
pass
else:
t += c
return t
def anti_vowel(text):
t=""
for c in text:
for i in "ieaouIEAOU":
if c==i:
c=""
else:
c=c
t=t+c
return t
This question already has answers here:
Loop "Forgets" to Remove Some Items [duplicate]
(10 answers)
Closed 8 years ago.
I'm going through some exercises in CodeAcademy. In one they ask you to write a function to remove all the vowels from a string.
Apparently my function works with different texts, but it's not working with: "Hey look Words!". That's weird. Which could be my error?
My code:
def anti_vowel(text):
vowels = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
letters = []
for char in text:
letters.append(char)
for i in vowels:
for j in letters:
if i==j:
letters.remove(j)
new_text = ''.join(letters)
print new_text
Your problem is that you are modifying letters while iterating over it. Instead, try building a new list (and a few other changes):
no_vowels = []
for j in letters:
if j not in vowels:
no_vowels.append(j)
new_text = ''.join(no_vowels)
You can always do like this. You have to use another variable for new string.
>>> vowels = ['a','e','i','o','u', 'A', 'E', 'I', 'O', 'U']
>>> string = "Hey look Words!"
>>> new_string = ""
>>> for s in string:
if s not in vowels:
new_string += s
>>> print new_string
Hy lk Wrds!
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
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.
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.
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'
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")
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])
vowels = ('a', 'e', 'i', 'o', 'u', 'A', 'I', 'E', 'O', 'U')
for char in text:
if char in vowels:
text = text.replace(char, '')
return text
One more simpler way can be extracting the non-vowel characters from string and returning them.
def anti_vowel(text):
newstring=""
for i in text:
if i not in "aeiouAEIOU":
newstring=newstring+i
text=newstring
return text
I know there are many correct solutions on this subject but I thought to add few fun ways of solving this problem.
If you come from a C++/C# or Java, you will tend to use something like compare then action using the index to remove the unwanted entry in a for loop. Python has the Remove and Del functions. Remove function uses the value and
del uses the index.The pythonic solution is in the last function. Lets see how we can do that:
Here we are using the index in a for loop and del function very similar in C++:
def remove_vol(str1):
#list2 = list1 # this won't work bc list1 is the same as list2 meaning same container#
list1 = list(str1)
list2 = list(str1)
for i in range(len(list1)):
if list1[i] in volwes:
vol = list1[i]
x = list2.index(vol)
del list2[x]
print(list2)
Using the remove function:
def remove_vol(str1):
list1 = list(str1)
list2 = list(str1)
for i in list1:
if i in volwes:
list2.remove(i)
print(list2)
Building new string that does not contain the unwanted chars using their indexes:
def remove_vol(str1):
list1 = list(str1)
clean_str = ''
for i in range(len(list1)):
if list1[i] not in volwes:
clean_str += ''.join(list1[i])
print(clean_str)
Same as in the solution in above but using the value:
def remove_vol(str1):
list1 = list(str1)
clean_str = ''
for i in list1:
if i not in volwes:
clean_str += ''.join(i)
print(clean_str)
How you should do it in python? Using list comprehension! It is beautiful:
def remove_vol(list1):
clean_str = ''.join([x for x in list1 if x.lower() not in volwes])
print(clean_str)
def anti_vowel(text):
new=[]
vowels = ("aeiouAEIOU")
for i in text:
if i not in vowels:
new.append(i)
return ''.join(new)
i hope this helps..
def anti_vowel(text):
new_text = ""
for i in text:
if i == 'a' or i == 'A':
pass
elif i == 'e' or i == 'E':
pass
elif i == 'I' or i == 'i':
pass
elif i == 'o' or i == 'O':
pass
elif i == 'u' or i == 'U':
pass
else:
new_text = new_text + i
return new_text
print anti_vowel('Hey look Words!')
My implementation:
# Ask the user for input:
user_input = input("enter a string with some vowels: ")
print("input string: " + str(user_input))
vowels = ('a','e','i','o','u','A','E','I','O','U')
new_string="";
for i in range(0,len(user_input),1):
if user_input[i] in vowels:
print ('found a vowel, removing...')
else:
new_string+=user_input[i]
print("I've removed the vowels for you. You're welcome! The new string is: " + new_string)
A fairly simple approach could be;
def anti_vowel(text):
t = ''
for c in text:
if c in "aeiouAEIOU":
pass
else:
t += c
return t
def anti_vowel(text):
t=""
for c in text:
for i in "ieaouIEAOU":
if c==i:
c=""
else:
c=c
t=t+c
return t
muutujad = list(input("Muutujad (sisesta formaadis A,B,C,...): "))
while "," in muutujad == True:
muutujad.remove(",")
print (muutujad)
My brain says that this code should remove all the commas from the list and in the end
the list should contain only ["A","B","C" ....] but it still contains all the elements. When i tried to visualize the code online, it said like [ "," in muutujad ] is always False but when i check the same command from the console it says it is True. I know it is a simple question but i would like to understand the basics.
You can use a list comprehension instead of a while loop:
muutujad = [elem for elem in muutujad if elem != ',']
Your if test itself is also wrong. You never need to test for == True for if in any case, that's what if does. But in your case you test the following:
("," in muutujad) and (muutujad == True)
which is always going to be False. In python, comparison operators like in and == are chained. Leaving off the == True would make your while loop work much better.
I'm not sure you understand what happens when you call list() on a string though; it'll split it into individual characters:
>>> list('Some,string')
['S', 'o', 'm', 'e', ',', 's', 't', 'r', 'i', 'n', 'g']
If you wanted to split the input into elements separated by a comma, use the .split() method instead, and you won't have to remove the commas at all:
>>> 'Some,string'.split(',')
['Some', 'string']
The best option here is to simply parse the string in a better way:
>>> muutujad = input("Muutujad (sisesta formaadis A,B,C,...): ").split(",")
Muutujad (sisesta formaadis A,B,C,...): A, B, C
>>> muutujad
['A', ' B', ' C']
str.split() is a much better option for what you are trying to do here.
What about list("Muutujad (sisesta formaadis A,B,C,...): ".replace(' ', ''))
Downvoter: I meant: this is how you do remove commas from string.
You do not convert your input from string to list and then remove your commas from the list, it's absurd.
you do: list(input('...').replace(' ', ''))
or you use split, as pointed out above.
I'm trying to add whole words from one string to another if they contain a certain character:
mylist = ["hahah", "hen","cool", "breaker", "when"]
newlist = []
for word in mylist:
store = word #stores current string
if 'h' in word: #splits string into characters and searches for 'h'
newlist += store #adds whole string to list
print newlist
the result I expect is:
newlist = ["hahah","hen","when"]
but instead I'm getting:
newlist = ['h', 'a', 'h', 'a', 'h', 'h', 'e', 'n', 'w', 'h', 'e', 'n']
How do I get my expected result?
Use append [docs]:
newlist.append(store)
Or shorter (using list comprehension [docs]):
newlist = [word for word in mylist if 'h' in word]
Why does newlist += store not work?
This is the same as newlist = newlist + store and is extending the existing list (on left side) by all the items in the sequence [docs] on the right side. If you follow the documentation, you will find this:
s + t the concatenation of s and t
In Python, not only lists are sequences, but strings are too (a sequence of characters). That means every item of the sequence (→ every character) is appended to the list.
Out of interest I decided to see which of the three solutions (the loop, the list comprehension and the filter() function) was the quickest. My test code and the results are below for anybody else who is interested.
Initialisation
>>> import timeit
>>> num_runs = 100000
>>> setup_statement = 'mylist = ["hahah", "hen","cool", "breaker", "when"]'
Loop
>>> loop_statement = """
newlist = []
for word in mylist:
if 'h' in word:
newlist.append(word)"""
>>> timeit.timeit(loop_statement, setup_statement, number=num_runs) / num_runs
4.3187308311462406e-06
List comprehension
>>> list_statement = "newlist = [word for word in mylist if 'h' in word]"
>>> timeit.timeit(list_statement, setup_statement, number=num_runs) / num_runs
2.9228806495666502e-06
Filter call
>>> filter_statement = """
filt = lambda x: "h" in x
newlist = filter(filt, mylist)"""
>>> timeit.timeit(filter_statement, setup_statement, number=num_runs) / num_runs
7.2317290306091313e-06
Results
List comprehension at 2.92us
Loop at 4.32us (48% slower than the list comprehension)
Filter call at 7.23us (148% slower than the list comprehension)
Another alternate syntax for expressing this is to use filter. Thus, an implementation for your problem would look something like
filt = lambda x: 'h' in x
newlist1 = filter(filt, mylist)
try to use:
newlist.append(store)