'String index out of range' error and I don't understand why
Question:
I’m trying to take an input, drop the vowels, and print the new phrase.
Code
Here’s the code I’m using.
phrase = input("Input: ")
for i in range(len(phrase)):
if str(phrase[i]) in ["a", "A", "e", "E", "i", "I", "O", "o", "u", "U"]:
phrase = str(phrase[i]).replace(phrase[i], "") # error here
print(phrase)
Issue
On line 3, I am getting the error:
string index out of range
I don’t understand how, since I thought I limited the index to the length of the phrase.
Even if there are better ways to create this script (and I would love any suggestions), I would also really love to know where what I’m doing is going wrong and how to fix it!
Answers:
If I am not wrong, it returns "IndexError: string index out of range", since you can only access one position of the string. By entering a single character or number it works perfectly.
Don’t modify the string while you iterate over it. Just keep the letters you want:
phrase = input("Input: ")
new = []
for c in phrase:
if c not in "aeiouAEIOU":
new.append(c)
phrase = ''.join(new)
print(phrase)
Or:
phrase = ''.join([c for c in phrase if c not in "aeiuoAEIUO"])
Looks like you’re updating phrase
while iterating through from 0 to the original length of phrase
. The second you drop a character in phrase, the max valid subscript decreases while i
will still reach the original phrase length.
You could do this better with filter
.
phrase = input("Input: ")
new_phrase = "".join(filter(lambda c: c not in "aAeEiIoOuU", phrase))
print(new_phrase)
It looks like the issue is that you are re-writing the entire phrase
variable with a singular character and then you are trying to loop over it again.
In the 4th line, you set phrase
equal to a single character, and then you try to loop over it again but then you have phrase[i]
, but phrase
itself now is just length of 1. So if i
is greater than 1 (it probably is) it can’t do that.
Also, you can loop directly over a string and it will return each character of the string directly.
Try building a new string in line 4 instead, something like
phrase = input("Input: ")
new_string = ''
for i in phrase:
if i not in ["a", "A", "e", "E", "i", "I", "O", "o", "u", "U"]:
new_string += i
print(new_string)
edit: update code based off of comments
I think you don’t need i
as index or range(len(phrase))
to replace a character or to drop certain character in phrase
string, If you’re intend to take an input, drop the vowels, and print the new phrase.
phrase = input("Input: ")
for i in phrase:
if i in ["a", "A", "e", "E", "i", "I", "O", "o", "u", "U"]:
phrase = phrase.replace(i, "")
print(phrase)
Spotted Issues
3 issues and 1 improvement:
for i in range(len(phrase)):
: (a) len
of string is a snapshot which will does not fit anymore as soon as the first vowel was removed. (b) indexed for-i loop can be replaced by a for-each loop for c in phrase
which loops through each character of a string
if str(phrase[I]) in ["a", "A", "e", "E", "i", "I", "O", "o", "u", "U"]
: (a) string-conversion is not needed, phrase[i]
or c
can be compared to string element already. (b) can directly compare if character is in a string of vowels: if c in "aAeEiIoOuU"
phrase = str(phrase[i]).replace(phrase[i], "")
: replace parts inside a whole, like a character inside a string using phrase = phrase.replace("a", "")
– don’t replace the single character at a position.
phrase = input("Input: ")
: to improve towards a reproducible example, provide the input as fixed given example: phrase = "Hello World with many Vowels"
instead depending on interactive user-input.
Solution
I would suggest a combination of the good answers here:
- loop for each character in string like suggested by Tim
- add to a
new_phrase
like suggested by LLSv2.0
- drop by replace with empty-string like tried by you and suggested by ANC
- compare agains given vowels from a string like
"aAeEiIoOuU"
like Tim did
I’m trying to take an input, drop the vowels, and print the new phrase.
Code
Here’s the code I’m using.
phrase = input("Input: ")
for i in range(len(phrase)):
if str(phrase[i]) in ["a", "A", "e", "E", "i", "I", "O", "o", "u", "U"]:
phrase = str(phrase[i]).replace(phrase[i], "") # error here
print(phrase)
Issue
On line 3, I am getting the error:
string index out of range
I don’t understand how, since I thought I limited the index to the length of the phrase.
Even if there are better ways to create this script (and I would love any suggestions), I would also really love to know where what I’m doing is going wrong and how to fix it!
If I am not wrong, it returns "IndexError: string index out of range", since you can only access one position of the string. By entering a single character or number it works perfectly.
Don’t modify the string while you iterate over it. Just keep the letters you want:
phrase = input("Input: ")
new = []
for c in phrase:
if c not in "aeiouAEIOU":
new.append(c)
phrase = ''.join(new)
print(phrase)
Or:
phrase = ''.join([c for c in phrase if c not in "aeiuoAEIUO"])
Looks like you’re updating phrase
while iterating through from 0 to the original length of phrase
. The second you drop a character in phrase, the max valid subscript decreases while i
will still reach the original phrase length.
You could do this better with filter
.
phrase = input("Input: ")
new_phrase = "".join(filter(lambda c: c not in "aAeEiIoOuU", phrase))
print(new_phrase)
It looks like the issue is that you are re-writing the entire phrase
variable with a singular character and then you are trying to loop over it again.
In the 4th line, you set phrase
equal to a single character, and then you try to loop over it again but then you have phrase[i]
, but phrase
itself now is just length of 1. So if i
is greater than 1 (it probably is) it can’t do that.
Also, you can loop directly over a string and it will return each character of the string directly.
Try building a new string in line 4 instead, something like
phrase = input("Input: ")
new_string = ''
for i in phrase:
if i not in ["a", "A", "e", "E", "i", "I", "O", "o", "u", "U"]:
new_string += i
print(new_string)
edit: update code based off of comments
I think you don’t need i
as index or range(len(phrase))
to replace a character or to drop certain character in phrase
string, If you’re intend to take an input, drop the vowels, and print the new phrase.
phrase = input("Input: ")
for i in phrase:
if i in ["a", "A", "e", "E", "i", "I", "O", "o", "u", "U"]:
phrase = phrase.replace(i, "")
print(phrase)
Spotted Issues
3 issues and 1 improvement:
for i in range(len(phrase)):
: (a)len
of string is a snapshot which will does not fit anymore as soon as the first vowel was removed. (b) indexed for-i loop can be replaced by a for-each loopfor c in phrase
which loops through each character of a stringif str(phrase[I]) in ["a", "A", "e", "E", "i", "I", "O", "o", "u", "U"]
: (a) string-conversion is not needed,phrase[i]
orc
can be compared to string element already. (b) can directly compare if character is in a string of vowels:if c in "aAeEiIoOuU"
phrase = str(phrase[i]).replace(phrase[i], "")
: replace parts inside a whole, like a character inside a string usingphrase = phrase.replace("a", "")
– don’t replace the single character at a position.phrase = input("Input: ")
: to improve towards a reproducible example, provide the input as fixed given example:phrase = "Hello World with many Vowels"
instead depending on interactive user-input.
Solution
I would suggest a combination of the good answers here:
- loop for each character in string like suggested by Tim
- add to a
new_phrase
like suggested by LLSv2.0 - drop by replace with empty-string like tried by you and suggested by ANC
- compare agains given vowels from a string like
"aAeEiIoOuU"
like Tim did