您正在遍历列表并同时从中删除元素。
首先,我需要确保您清楚地了解char
in的作用for char in textlist: ...
。以我们到达字母“l”的情况为例。情况不是这样的:
['H', 'e', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
^
char
char
列表中字母“l”的位置和位置之间没有联系。如果您修改char
,列表将不会被修改。情况更像是这样的:
['H', 'e', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!']
^
char = 'l'
请注意,我保留了该^
符号。这是管理for char in textlist: ...
循环的代码用来跟踪其在循环中的位置的隐藏指针。每次进入循环体,指针都会前进,指针所引用的字母会被复制到char
.
当您连续有两个元音时,您的问题就会出现。我会告诉你从你到达“l”的那一点会发生什么。请注意,我还将“look”一词更改为“leap”,以便更清楚地了解发生了什么:
提前指向下一个字符 ('l') 的指针并复制到char
['H', 'e', 'y', ' ', 'l', 'e', 'a', 'p', ' ', 'W', 'o', 'r', 'd', 's', '!']
-> ^
char = 'l'
char
('l') 不是元音,所以什么也不做
提前指向下一个字符 ('e') 的指针并复制到char
['H', 'e', 'y', ' ', 'l', 'e', 'a', 'p', ' ', 'W', 'o', 'r', 'd', 's', '!']
-> ^
char = 'e'
char
('e') 是元音,所以删除第一次出现的char
('e')
['H', 'e', 'y', ' ', 'l', 'e', 'a', 'p', ' ', 'W', 'o', 'r', 'd', 's', '!']
^
['H', 'e', 'y', ' ', 'l', 'a', 'p', ' ', 'W', 'o', 'r', 'd', 's', '!']
^
['H', 'e', 'y', ' ', 'l', <- 'a', 'p', ' ', 'W', 'o', 'r', 'd', 's', '!']
^
['H', 'e', 'y', ' ', 'l', 'a', 'p', ' ', 'W', 'o', 'r', 'd', 's', '!']
^
提前指向下一个字符 ('p') 的指针并复制到char
['H', 'e', 'y', ' ', 'l', 'a', 'p', ' ', 'W', 'o', 'r', 'd', 's', '!']
-> ^
char = 'p'
当你删除'e'时,'e'之后的所有字符都向左移动了一个位置,所以就好像remove
指针前进了一样。结果是您跳过了“a”。
通常,您应该避免在迭代列表时修改列表。最好从头开始构建一个新列表,Python 的列表推导式是执行此操作的完美工具。例如
print ''.join([char for char in "Hey look Words" if char.lower() not in "aeiou"])
但是如果你还没有学习理解,最好的方法可能是:
text = "Hey look Words!"
def anti_vowel(text):
textlist = list(text)
new_textlist = []
for char in textlist:
if char.lower() not in 'aeiou':
new_textlist.append(char)
return "".join(new_textlist)
print anti_vowel(text)