在下面的代码中,目标是创建一个名为 anti_vowel 的函数,用于消除给定字符串中的元音。虽然该函数看起来很简单,但在处理字符串“Hey Look Words!”时,它会出现问题,产生“Hy lk Words!”。该函数无意中未能删除“look”中的最后一个“o”。
text = "Hey look Words!" def anti_vowel(text): textlist = list(text) for char in textlist: if char.lower() in 'aeiou': textlist.remove(char) return "".join(textlist) print anti_vowel(text)
问题源于在迭代列表时修改列表。这种方法会导致意想不到的后果。为了纠正这个问题,应该创建输入列表的副本,以便有效地删除元音而不影响后续元素的位置。
for char in textlist[:]: #shallow copy of the list # etc
为了更好地理解,请考虑以下代码,该代码说明了问题:
textlist = ['H', 'e', 'y', ' ', 'l', 'o', 'o', 'k', ' ', 'W', 'o', 'r', 'd', 's', '!'] for char in textlist: print(char, textlist)
预期输出将是字符串的垂直列表,但实际输出是:
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!
随着循环的进行,元素将从列表中删除,跳过下一个元素。在“look”的情况下,会跳过第二个“o”,因为索引已超出它。因此,“Words”中的最后一个“o”被删除,而不是“look”中的那个。
利用 Python 的列表推导式提供了一种更清晰、更简洁的解决方案:
def remove_vowels(text): # function names should start with verbs! :) return ''.join(ch for ch in text if ch.lower() not in 'aeiou')
以上是为什么在迭代期间修改列表时我的循环无法从字符串中删除所有元音?的详细内容。更多信息请关注PHP中文网其他相关文章!