If you are insistent upon using the
replace method, then some adjustment will be necessary.
You won't need a
newstring variable, since all the work can be done in place on the inputs.
You will not have to iterate over the the inputs, only the vowels.
for x in 'aeiouAEIOU':
c = c.replace(x, '')
If no limit is set on
replace then it is greedy by default. That means all instances of a needle in the haystack are removed at once.
We can also see there is no need for a conditional. A brute force approach might be doing more work than necessary, but needs no logic. It's purely search and destroy.
Now let's look at the mechanics of the following line, and why it doesn't work as expected...
replace is not an in-pace method. Nothing actually happens to the string. The method takes a snapshot and builds a new string that incorporates the replacement string.
In actual fact, the first replacement cycle of your code did take place, and was assigned to
newstring, but the next replacement cycle overwrote it. Since the
e is still in the haystack string, it is in the resulting string.
We make this an in-place operation by assigning back onto the same variable. We are replacing its value with each iteration.