python - Loop "Forgets" to Remove Some Items -


this question has answer here:

in code trying create function anti_vowel remove vowels (aeiouaeiou) string. think should work ok, when run it, sample text "hey words!" returned "hy lk words!". "forgets" remove last 'o'. how can be?

text = "hey words!"  def anti_vowel(text):      textlist = list(text)      char in textlist:         if char.lower() in 'aeiou':             textlist.remove(char)      return "".join(textlist)  print anti_vowel(text) 

you're modifying list you're iterating over, bound result in unintuitive behavior. instead, make copy of list don't remove elements you're iterating through.

for char in textlist[:]: #shallow copy of list     # etc 

to clarify behavior you're seeing, check out. put print char, textlist @ beginning of (original) loop. you'd expect, perhaps, print out string vertically, alongside list, you'll this:

h ['h', 'e', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'w', 'o', 'r', 'd', 's', '!'] e ['h', 'e', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'w', 'o', 'r', 'd', 's', '!']   ['h', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'w', 'o', 'r', 'd', 's', '!'] # ! l ['h', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'w', 'o', 'r', 'd', 's', '!'] o ['h', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'w', 'o', 'r', 'd', 's', '!'] k ['h', 'y', ' ', 'l', 'o', 'k', ' ', 'w', 'o', 'r', 'd', 's', '!'] # problem!!   ['h', 'y', ' ', 'l', 'o', 'k', ' ', 'w', 'o', 'r', 'd', 's', '!'] w ['h', 'y', ' ', 'l', 'o', 'k', ' ', 'w', 'o', 'r', 'd', 's', '!'] o ['h', 'y', ' ', 'l', 'o', 'k', ' ', 'w', 'o', 'r', 'd', 's', '!']  d ['h', 'y', ' ', 'l', 'k', ' ', 'w', 'o', 'r', 'd', 's', '!'] s ['h', 'y', ' ', 'l', 'k', ' ', 'w', 'o', 'r', 'd', 's', '!'] ! ['h', 'y', ' ', 'l', 'k', ' ', 'w', 'o', 'r', 'd', 's', '!'] hy lk words! 

so what's going on? nice for x in y loop in python syntactic sugar: still accesses list elements index. when remove elements list while iterating on it, start skipping values (as can see above). result, never see second o in "look"; skip on because index has advanced "past" when deleted previous element. then, when o in "words", go remove first occurrence of 'o', 1 skipped before.


as others have mentioned, list comprehensions better (cleaner, clearer) way this. make use of fact python strings iterable:

def remove_vowels(text): # function names should start verbs! :)     return ''.join(ch ch in text if ch.lower() not in 'aeiou') 

Comments

Popular posts from this blog

java - Jasper subreport showing only one entry from the JSON data source when embedded in the Title band -

serialization - Convert Any type in scala to Array[Byte] and back -

SonarQube Plugin for Jenkins does not find SonarQube Scanner executable -