我已输入以下代码删除元音,但它并不专门用于重复字母!只需运行我的代码即可了解问题!
def anti_vowel(text):
text=list(text)
for i in text:
if i=='e' or i=='E' or i=='a' or i=='O' or i=='o' or \
i=='A' or i=='u' or i=='U' or i=='i' or i=='I':
text.remove(i)
text1=''.join(text)
text2=str(text1)
return text
print anti_vowel("Hey Look World!")
我搜索了互联网并找到了将我的代码更改为:
的答案for i in text[:]:
告诉我发生了什么?
答案 0 :(得分:2)
正如文档明确指出的那样,list.remove
将:
删除第一次出现的值
当然,它不会删除所有出现的值。这就像抱怨名为print
的函数打印值而不是将它们乘以3。
如果要删除所有出现的值,可以通过多种方式执行此操作。例如,您可以在循环中调用remove
,直到它引发ValueError
。
但是你的代码存在更大的问题。
首先,在迭代它时,不允许从列表中删除内容。这将导致各种坏事 - 最常见的是,它会导致迭代跳过许多值。你通常可以通过向后迭代来解决这个问题,但是当你使用像remove
这样从前面工作的函数时,这将不起作用。您几乎总能通过迭代列表的副本来解决这个问题(这就是您的for i in text[:]:
所做的事情; text[:]
是整个列表的一个切片的副本。)
其次,你正在重复你的工作。为什么只需拨打'e'
手动查找每个remove
,以便它可以从头开始搜索第一个e
?要么摆脱外部循环,只需调用remove
直到完成,或者除去remove
并使用del
删除你已经完成的值搜索的工作 - 或者最重要的是,重新组织您的代码,以便您可以按顺序完成所有操作。
所以,有三个半选项:
for vowel in 'AEIOUaeiou':
while True:
try:
text.remove(vowel)
except ValueError:
break
for i, letter in reversed(enumerate(text)):
if letter in 'AEIOUaeiou':
del text[i]
for i, letter in enumerate(text[:]):
if letter in 'AEIOUaeiou':
del text[i]
text = [letter for letter in text if letter not in 'AEIOUaeiou']
或者,正如马蒂亚斯指出的那样,在这种情况下,正则表达式可能是更好的答案;唯一的问题是你必须将列表转换为字符串才能在其上运行re.sub
,然后将其转换回列表......但这很容易:
text = list(re.sub(r'[aeiou]', '', ''.join(text), flags=re.IGNORECASE))