Iteration is an indexed operation. When you remove an item from a list while iterating over it, you essentially change the indices of every item in the list that follows the item you removed. When you loop over the list
['h','e','y',' ','l','o','o','k',' ','w','o','r','d','s']
whilst removing an item in 'aeiou'
, on the second iteration of the loop, you remove 'e'
from your list and your left with
['h','y',' ','l','o','o','k',' ','w','o','r','d','s']
then on the third iteration, instead of testing your if statement on the y
, which was originally in the third position, it is now testing it on the ' '
, which is what is in the third position of the the modified list.
mylist.remove(x)
will search for the first matching value of x
inmylist
and remove it. When your loop gets to the first 'o'
in the list, it removes it, thereby changing the index of the following 'o'
by -1
. On the next iteration of the loop, it is looking at 'k'
instead of the subsequent 'o'
.
However, why then did your function remove the first two 'o'
s and not the last one?
Your loop looked at the first 'o'
, not the second 'o'
, and looked at the third 'o'
. In total your loop found two matches for 'o'
and performed the remove
function on both. And again, since the remove
function will find the first matching item in the list and remove it, that's why it removed the first two 'o'
s, although for the removal of the second 'o'
your loop was actually iterating over the third 'o'
.
You were fortunate to have done this test on a string with consecutive vowels. Had you done it on a string without consecutive vowels, you would have removed all the vowels with your function and it would have appeared to work as you intended.