Removing characters from string Python - python

I'm trying to write a function that gets rid of the vowels in a given string, but it seems to not behave the way it should do...
def anti_vowel(text):
for c in text:
if c in "aeiouAEIOU":
no_vowel = text.replace(c, '')
return no_vowel
print(anti_vowel('Hello World')
so instead of printing
Hll Wrld
It prints
Hell Wrld
Thanks (in advance) for helping

The problem is that no_vowel only has the value of the last time that text.replace(c, '') was executed. Another issue is that no_vowel only gets a value when there is actually a vowel to remove; the code would fail on anti_vowel('vwllss'). Furthermore, you don't have to check whether a character is contained in the text before calling str.replace().
This should work:
def anti_vowel(text):
for vowel in "aeiouAEIOU":
text = text.replace(vowel, '')
return text
print(anti_vowel('Hello World'))
As others indicated, another approach would be to write code in a different way:
def anti_vowel(text):
''.join(c for c in text if c not in 'aeiouAEIOU')
Please do use a generator expression in ''.join() and not a list comprehension; such a list comprehension would allocate memory unnecessarily.

You can use string.translate() for this. For example:
def anti_vowel(text):
return text.translate(None, "aeiouAEIOU")
print(anti_vowel("hello world"))
With Python 3 the delete argument is gone, but you can still do it by mapping a character to None.
def anti_vowel_py3(text):
return text.translate({ord(i): None for i in "aeiouAEIOU"})
print(anti_vowel_py3("hello world"))

Your code doesnt work because every iteration you assign no_vowel with the text all over again and you iterate the text's letters what you shouldnt because replace already does it. You should write it like that:
def anti_vowel(text):
no_vowel = text
for c in 'aeiouAEIOU':
no_vowel = no_vowel.replace(c, '')
return no_vowel
Or, you could use a list comprehension. More Pythonic and faster to run:
def anti_vowel(text):
return ''.join([c for c in text if c not in 'aeiouAEIOU])

In every iteration of the loop, text is "Hello World", and the last vowel of text is "o", so at the end of the loop, no_vowel is "Hell Wrld".
In python2.7, use method translate instead. Here is the official document:
translate(...)
S.translate(table [,deletechars]) -> string
Return a copy of the string S, where all characters occurring
in the optional argument deletechars are removed, and the
remaining characters have been mapped through the given
translation table, which must be a string of length 256 or None.
If the table argument is None, no translation is applied and
the operation simply removes the characters in deletechars.
"Hello World".translate(None, "aeiouAEIOU") gives the correct result "Hll Wrld"
Also, re.sub('[aeiouAEIOU]', "", "Hello World") works for both python2.7 and python3

Related

How to remove a group of characters from a string in python including shifting

For instance I have a string that needs a certain keyword removed from a string so lets say may key word iswhatthemomooofun and I want to delete the word moo from it, I have tried using the remove function but it only removes "moo" one time, but now my string is whatthemoofun and I can seem to remove it is there anyway I can do that?
You can use the replace in built function
def str_manipulate(word, key):
while key in word:
word = word.replace(key, '')
return word
Have you tried using a while loop? You could loop through it until it doesn't find your keyword anymore then break out.
Edit
Cause answer could be improved by an example, take a look at the general approach it deals with:
Example
s = 'whatthemomooofun'
while 'moo' in s:
s= s.replace('moo','')
print(s)
Output
whatthefun
original_string = "!(Hell#o)"
characters_to_remove = "!()#"
new_string = original_string
for character in characters_to_remove:
new_string = new_string.replace(character, "")
print(new_string)
OUTPUT
Hello

How does one go about removing a character in a string using a for loop in python 3?

The aim of the code is to go through a string using a for loop and remove certain punctuations specifically (“,”,“.”,“?”,“!”, “;”,“:”) with the statement if c in (“,”,“.”,“?”,“!”, “;”,“:”) included. So for I have tried using stringting.replace(stringting[i],"") in the 5th line of the code below and then I tried using stringting.translate() in line 5 with no luck. Why is it not working?
def removePun(stringting):
new_string = ""
for i in range (0,len(stringting)):
if stringting[i] in (",",".","","?",";",":"):
new_string = stringting.translate({ord(stringting[i]): None})
return new_string
Instead of testing if a character is in the tuple and then removing it, it would be simpler to test if it is not in the tuple and then add it to the result - or, better, use a list comprehension which only takes one line of code. So:
punctuation = (",",".","","?",";",":")
def removePun(string):
return "".join([c for c in string if c not in punctuation])
There are numerous approaches to this problem. Try this,
def remove_punctuation(string):
result = ""
for punc in ",:;!.?":
result = result.replace(punc, "")
return result
If you want to use str.translate() you need to make a translation table:
t = str.translate("", "", ",:;!.?")
some_word.translate(t)
Using str.translate is ideal in the case of single-character removals. I go into more details for a duplicate of this question here.

a mistake I keep having with for loops and return statements

I have been noticing a problem I am having whenever I try to make a function that takes changes a string or a list then returns it.
I will give you an example of this happening with a code I just wrote:
def remove_exclamation(string):
string.split(' ')
for i in string:
i.split()
for char in i:
if char == '!':
del char
''.join(i)
' '.join(string)
return string
For instance, I create this code to take a string as its parameter, remove any exclamation in it, the return it changed. The input and output should look like this:
>>>remove_exclamation('This is an example!')
'This is an example'
But instead I get this:
>>>remove_exclamation('This is an example!')
'This is an example!'
The function is not removing the exclamation in the output, and is not doing what I intended for it to day.
How can I keep avoiding this when I make for loops, nested for loops etc?
You write your code and formulate your question as if it was possible to modify strings in Python. It is not possible.
Strings are immutable. All functions which operate on strings return new strings. They do not modify existing strings.
This returns a list of strings, but you are not using the result:
string.split(' ')
This also:
i.split()
This deletes the variable named char. It does not affect the char itself:
del char
This creates a new string which you do not use:
''.join(i)
This also:
' '.join(string)
All in all, almost every line of the code is wrong.
You probably wanted to do this:
def remove_exclamation(string):
words = string.split(' ')
rtn_words = []
for word in words:
word_without_exclamation = ''.join(ch for ch in word if ch != '!')
rtn_words.append(word_without_exclamation)
return ' '.join(rtn_words)
But in the end, this does the same thing:
def remove_exclamation(string):
return string.replace('!', '')
Without clearly knowing the intentions of your function and what you are attempting to do. I have an alternative to the answer that zvone gave.
This option is to remove any characters that you have not defined in an allowed characters list:
characters = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ "
test_string = "This is an example!"
test_string = ''.join(list(filter(lambda x: x in characters, test_string)))
print(test_string)
This outputs:
This is an example
Note, this is the Python 3 version.
Python 2, you do not need the ''.join(list())
Doing it this way would allow you to define any character that you do not want present in your string, and it will remove them.
You can even do the reverse:
ignore_characters= "!"
test_string = "This is an example!"
test_string = ''.join(list(filter(lambda x: x not in ignore_characters, test_string)))
print(test_string)
Strings are immutable in Python. And you cannot change them. You can however, re-assign there values.
That is where your problem lies. You never reassign the value of your strings, when you call .split() on them.
But there are also others errors in your program such as:
Your indention
The fact that your just returning the string thats passed into the function
Your use of the del statement
etc.
Instead, create a new string by iterating through the old one and filtering out the character(s) you do not want, via list comprehension and ''.join().
def remove_exclamation(string):
return ''.join([char for char in string if char != '!'])
But as #Moses has already said in the comments, why not just use str.replace()?:
string = string.replace('!', '')
def remove_exclamation(string):
#you think you are splitting string into tokens
#but you are not assigning the split anywhere...
string.split(' ')
#and here you are cycling through individual _chars_ in string which was not affected by the split above ;-)
for i in string:
#and now you are splitting a 1-char string and again not assigning it.
i.split()
And string is still your input param, which I assume is of type str. And immutable.
On top of which, if you were import/using the string module, you would be shadowing it
A big part of your confusion is knowing when the methods mutate the objects and when they return a new object. In the case of strings, they never mutate, you need to assign the results to a new variable.
On a list however, and the join() somewhere makes me think you want to use a list, then methods generally change the object in place.
Anyway, on to your question:
def remove_exclamation(inputstring, to_remove="!"):
return "".join([c for c in inputstring if c != to_remove])
print (remove_exclamation('This is an example!'))
output:
This is an example

replace() function is not replacing 'e' character

My code should recognize the vowel letters and remove them from input string using the replace() function. However it works fine except for the 'e' letter.
If the input is "Hey look Words!" the output is "Hey lk Wrds!".
It identifies the 'e' only if if the "vowels" string is equal to "e" or "eE" only!
I am curious to know why?
def anti_vowel(text):
vowles="AaEeOoIiUu"
newstr=""
for i in text:
if i in vowles:
newstr=text.replace(i,"")
return newstr
You are placing only the last replacement result in newstr. All your previous str.replace() results are discarded.
For your input text Hey look Words!, the last vowel encountered is o so only o is replaced. The e replacement did take place and was stored in newstr but that value was then discarded when you set newstr to the result of the o replacement. It thus depends on the input string what vowel exactly will remain replaced; for the sentence 'The cat sat on the mat' it'll be a as that is the last vowel you test and replace.
Just loop directly over vowels and replace each of those characters; it is save to call str.replace() where the first argument is not present. Store the result back in text so that any subsequent replacements stick:
def anti_vowel(text):
vowels = "AaEeOoIiUu"
for vowel in vowels:
text = text.replace(vowel, "")
return text
Better still, use the str.translate() method to replace all vowels in one go:
# Python 2 version
def anti_vowel(text):
vowels = "AaEeOoIiUu"
return text.translate(None, vowels)
# Python 3 version
def anti_vowel(text):
vowels = str.maketrans(dict.fromkeys("AaEeOoIiUu"))
return text.translate(vowels)
str.translate() makes all replacements at once; the method changed between Python 2 str and Python 3 str, but in both versions all the vowels are ignored as the new string is built, without any further loops.
There's no reason to iterate through all the letters in the word; the replace() method does that for you. And you are erasing newstr every time, so by the end, all you're doing is replacing u. Here's what you need to do.
def anti_vowel(text):
vowels = "AaEeIiOoUu"
for i in vowels:
text = text.replace(i, "")
return text
This way, each time you replace text, you save and keep the replaced string. What you were doing earlier was making newstr into text without A, then replacing newstr with text sans a (but with A), so on and so forth. The end result was text without u but with everything else.
You should change your code to:
def anti_vowel(text):
vowles="AaEeOoIiUu"
newstr=text
for i in newstr:
if i in vowles:
newstr=newstr.replace(i,"")
return newstr
Then you will acummulate each replacement in your final string.
The way you are doing you always use the original string and replace only one group of chars ('Ee', 'Aa', etc...) in each iteration. So, in the end, you get a result of only one of these groups replaced in the original string.

How do you filter a string to only contain letters?

How do I make a function where it will filter out all the non-letters from the string? For example, letters("jajk24me") will return back "jajkme". (It needs to be a for loop) and will string.isalpha() function help me with this?
My attempt:
def letters(input):
valids = []
for character in input:
if character in letters:
valids.append( character)
return (valids)
If it needs to be in that for loop, and a regular expression won't do, then this small modification of your loop will work:
def letters(input):
valids = []
for character in input:
if character.isalpha():
valids.append(character)
return ''.join(valids)
(The ''.join(valids) at the end takes all of the characters that you have collected in a list, and joins them together into a string. Your original function returned that list of characters instead)
You can also filter out characters from a string:
def letters(input):
return ''.join(filter(str.isalpha, input))
or with a list comprehension:
def letters(input):
return ''.join([c for c in input if c.isalpha()])
or you could use a regular expression, as others have suggested.
import re
valids = re.sub(r"[^A-Za-z]+", '', my_string)
EDIT: If it needs to be a for loop, something like this should work:
output = ''
for character in input:
if character.isalpha():
output += character
See re.sub, for performance consider a re.compile to optimize the pattern once.
Below you find a short version which matches all characters not in the range from A to Z and replaces them with the empty string. The re.I flag ignores the case, thus also lowercase (a-z) characters are replaced.
import re
def charFilter(myString)
return re.sub('[^A-Z]+', '', myString, 0, re.I)
If you really need that loop there are many awnsers, explaining that specifically. However you might want to give a reason why you need a loop.
If you want to operate on the number sequences and thats the reason for the loop consider replacing the replacement string parameter with a function like:
import re
def numberPrinter(matchString) {
print(matchString)
return ''
}
def charFilter(myString)
return re.sub('[^A-Z]+', '', myString, 0, re.I)
The method string.isalpha() checks whether string consists of alphabetic characters only. You can use it to check if any modification is needed.
As to the other part of the question, pst is just right. You can read about regular expressions in the python doc: http://docs.python.org/library/re.html
They might seem daunting but are really useful once you get the hang of them.
Of course you can use isalpha. Also, valids can be a string.
Here you go:
def letters(input):
valids = ""
for character in input:
if character.isalpha():
valids += character
return valids
Not using a for-loop. But that's already been thoroughly covered.
Might be a little late, and I'm not sure about performance, but I just thought of this solution which seems pretty nifty:
set(x).intersection(y)
You could use it like:
from string import ascii_letters
def letters(string):
return ''.join(set(string).intersection(ascii_letters))
NOTE:
This will not preserve linear order. Which in my use case is fine, but be warned.

Categories

Resources