Reputation: 3
I'm using the codeacademy python beginner's course. I'm supposed to define a function that takes a string and returns it without vowels. My function removes some vowels, but usually not all, varying with the specific string and without a clear pattern. My code's below, please look over it to see if you're able to find my error:
def anti_vowel(text):
a = len(text)
b = 0
letters = []
while a > 0:
letters.append(text[b])
a -= 1
b += 1
for item in letters:
if item in "aeiouAEIOU":
letters.remove(item)
final = ""
return final.join(letters)
Upvotes: 0
Views: 91
Reputation: 2701
Adding on to what the rest has already said, that you should not modify the iterable when looping through it, here is my shorter version of the whole code:
def anti_vowel(text):
return text.translate(None, "aeiouAEIOU")
Python already has a "built-in text remover", you can read more about translate here.
Upvotes: 0
Reputation: 104802
The issue you have is that you're iterating over your list letters
and modifying it at the same time. This causes the iteration to skip certain letters in the input without checking them.
For instance, if your text
string was 'aex'
, the letters
list would become ['a', 'e', 'x']
. When you iterate over it, item
would be 'a'
on the first pass, and letters.remove('a')
would get called. That would change letters
to ['e', 'x']
. But list iteration works by index, so the next pass through the loop would not have item
set to 'e'
, but instead to the item in the next index, 'x'
, which wouldn't get removed since it's not a vowel.
To make the code work, you need to change its logic. Either iterate over a copy of the list, iterate in reverse, or create a new list with the desired items rather than removing the undesired ones.
Upvotes: 3
Reputation: 399
not sure how exactly your function is supposed to work as there are quite a few errors with it. I will walk you through a solution I would come up with.
def anti_vowel(text):
final = ''
for letter in text:
for vowel in 'aeiouAEIOU':
if (letter == vowel):
letter = ""
final += letter
print final
return final
anti_vowel('AEIOUaeiou qwertyuiopasdfghjklzxcvbnm')
We initialize the function and call the passed param text
def anti_vowel(text):
We will initialize final as an empty string
final = ''
We will look at all the letters in the text passed in
for letter in text:
Every time we do this we will look at all of the possible vowels
def anti_vowel(text):
If any of these match the letter we are checking, we will make this letter an empty string to get rid of it.
if (letter == vowel):
letter = ""
Once we have checked it against every vowel, if it is a vowel, it will be an empty string at this point. If not it will be a string containing a consonant. We will add this value to the final string
final += letter
Print the result after all the checks and replacing has completed.
print final
Return the result
return final
Passing this
anti_vowel('AEIOUaeiou qwertyuiopasdfghjklzxcvbnm')
Will return this
qwrtypsdfghjklzxcvbnm
Upvotes: 0
Reputation: 882426
If you try it with a string containing consecutive a
characters (or any vowel), you'll see why.
The actual remove
call modifies the list so the iterator over that list will no longer be correct.
There are many ways you can fix that but perhaps the best is to not use that method at all. It makes little sense to make a list which you will then remove the characters from when you can just create a brand new string, along the lines of:
def anti_vowel (str):
set ret_str to ""
for ch as each character in str:
if ch is not a vowel:
append ch to ret_str
return ret_str
By the way, don't mistake that for Python, it's meant to be pseudo-code to illustrate how to do it. It just happens that, if you ignore all the dark corners of Python, it makes an ideal pseudo-code language :-)
Since this is almost certainly classwork, it's your job to turn that into your language of choice.
Upvotes: 0
Reputation: 342
I think @Blckknght hit the nail on the head. If I were presented with this problem, I'd try something like this:
def anti_vowel(text):
no_vowels = ''
vowels = 'aeiouAEIOU'
for a in text:
if a not in vowels:
no_vowels += a
return no_vowels
Upvotes: 1
Reputation: 174708
You'll always get unexpected results if you modify the thing that you are looping over, inside the loop - and this explains why you are getting strange values from your function.
In your for loop, you are modifying the object that you are supposed to be looping over; create a new object instead.
Here is one way to go about it:
def anti_vowel(text):
results = [] # This is your new object
for character in text: # Loop over each character
# Convert the character to lower case, and if it is NOT
# a vowel, add it to return list.
if not character.lower() in "aeiou":
results.append(character)
return ''.join(results) # convert the list back to a string, and return it.
Upvotes: 2