我对编程很新,并且已经开始使用Python了。我正在解决各种问题,以便更好地理解我的理解。
我正在尝试定义一个从字符串中删除元音的函数。这就是我的尝试:
def anti_vowel(text):
new = []
for i in range(len(text)):
new.append(text[i])
print new
for x in new:
if x == "e" or x == "E" or x == "a" or x == "A" or x == "i" or x == "I" or x == "o" or x == "O" or x == "u" or x == "U":
new.remove(x)
return "".join(new)
这是从字符串的第一个单词中删除元音,但不是最后一个单词:
例如:
anti_vowel("Hey look words!")
returns: "Hy lk words!"
有人可以解释我哪里出错了所以我可以从中吸取教训吗?
谢谢:)
答案 0 :(得分:5)
你should not delete items from a list while iterating through it。你会在Stack Overflow上找到很多帖子来解释原因。
我会使用filter
函数
>>> vowels = 'aeiouAEIOU'
>>> myString = 'This is my string that has vowels in it'
>>> filter(lambda i : i not in vowels, myString)
'Ths s my strng tht hs vwls n t'
作为一个函数编写,这将是
def anti_vowel(text):
vowels = 'aeiouAEIOU'
return filter(lambda letter : letter not in vowels, text)
测试
>>> anti_vowel(myString)
'Ths s my strng tht hs vwls n t'
答案 1 :(得分:2)
你好像已经向后看了一下。首先,请注意:
new = []
for i in range(len(text)):
new.append(text[i])
只是:
new = list(text)
其次,为什么不在append
之前检查,而不是之后检查?然后你只需要迭代一次字符。这可能是:
def anti_vowel(text):
"""Remove all vowels from the supplied text.""" # explanatory docstring
non_vowels = [] # clear variable names
vowels = set("aeiouAEIOU") # sets allow fast membership tests
for char in text: # iterate directly over characters, no need for 'i'
if char not in vowels: # test membership of vowels
non_vowels.append(char) # add non-vowels only
return "".join(non_vowels)
一个简单的例子:
>>> anti_vowel("Hey look words!")
'Hy lk wrds!'
这进一步简化为list comprehension:
def anti_vowel(text):
"""Remove all vowels from the supplied text."""
vowels = set("aeiouAEIOU")
return "".join([char for char in text if char not in vowels])
答案 2 :(得分:1)
您可以使用列表comp:
def anti_vowel(text):
vowels = 'aeiouAEIOU'
return "".join([x for x in text if x not in vowels])
print anti_vowel("Hey look words!")
Hy lk wrds!
列表理解过滤单词中的元音。
答案 3 :(得分:0)
你也可以简洁地理解它:
def anti_vowel(text):
return ''.join(ch for ch in text if ch.upper() not in 'AEIOU')
答案 4 :(得分:0)
迭代是一种索引操作。当您在迭代它时从列表中删除项目时,您实际上更改了列表中您删除的项目后面的每个项目的索引。循环遍历列表时
['h','e','y',' ','l','o','o','k',' ','w','o','r','d','s']
同时删除'aeiou'
中的项目,在循环的第二次迭代中,您从列表中删除'e'
,然后用
['h','y',' ','l','o','o','k',' ','w','o','r','d','s']
然后在第三次迭代中,而不是在最初位于第三位置的y
上测试你的if语句,而不是在' '
上测试它,这就是修改后的清单的第三个位置。
mylist.remove(x)
将在x
中搜索mylist
的第一个匹配值并将其删除。当您的循环到达列表中的第一个'o'
时,它会将其删除,从而将'o'
的索引更改为-1
。在循环的下一次迭代中,它会查看'k'
而不是后续的'o'
。
但是,为什么你的函数会删除前两个'o'
而不是最后一个?
您的循环查看了第一个'o'
,而不是第二个'o'
,并查看了第三个'o'
。总的来说,你的循环找到了'o'
的两个匹配项,并在两者上执行了remove
函数。同样,由于remove
函数会在列表中找到第一个匹配项并将其删除,这就是为什么它删除了前两个'o'
,尽管删除了第二个'o'
你的循环实际上正在迭代第三个'o'
。
你很幸运在连续元音的字符串上完成了这个测试。如果你在没有连续元音的字符串上完成它,你就可以删除所有带有你的功能的元音,它本来可以按你的意图工作。