判断一个单词中一半的字母是否是元音
就像标题所说的,我想知道一个单词中的元音字母是否至少占字母总数的一半。
这是我的代码:
def mostlyVowels(words):
vowel = 'aAeEiIoOuU'
words.split()
ans = []
for word in words:
for letter in word:
isvowel = 0
if letter in vowel:
isvowel += 1
if isvowel > ((len(word))/2):
ans.append(word)
return ans
# call mostlyvowels
words = 'Our lives begin to end the day we become silent about things that matter'
print(mostlyVowels(words))
所以我应该得到的是 ['our', 'about'],但我得到的是:
['O', 'u', 'i', 'e', 'e', 'i', 'o', 'e', 'e', 'a', 'e', 'e', 'o', 'e', 'i', 'e', 'a', 'o', 'u', 'i', 'a', 'a', 'e']
谢谢你花时间来帮忙。
8 个回答
1
words.split()
这个方法不会直接改变变量 words
的内容,它只是返回一个列表,所以你需要把这个返回的列表赋值给一个临时变量。或者,你也可以直接在你的 for 循环中调用它,这样就省去了中间变量:
vowel = 'aAeEiIoOuU'
ans = []
for word in words.split():
# etc.
其次,在你的第二个 for 循环中,你每次都把 isvowel
重新设置为 0,这样它就永远不会大于 1。你应该把这个赋值放到循环外面:
isvowel = 0
for letter in word:
if letter in vowel:
isvowel += 1
if isvowel > ((len(word))/2):
ans.append(word)
# etc.
2
为了好玩,这里把Darren Ringer的算法用一行代码的方式写出来,使用了列表推导式:
#! /usr/bin/env python
def mostlyVowels(words):
return [w for w in words.split() if sum((-1, 1)[c in 'aeiou'] for c in w.lower()) >= 0]
def main():
words = 'Our lives begin to end the day we become silent about things that matter'
print(mostlyVowels(words))
if __name__ == '__main__':
main()
输出结果
['Our', 'to', 'we', 'become', 'about']
我修改了测试内容,让它包含那些至少有一半字母是元音字母的单词,符合问题的要求。
2
s = 'Our lives begin to end the day we become silent about things that matter'
words = s.split() # get whitespace-separated words
print([w for w in words if is_vowel_word(w)]) # result
这里的 is_vowel_word()
可能是:
def is_vowel_word(word, vowels=set('aeiou')):
"""Whether half of the letters in a word are vowels."""
letters = set(word.lower()) # count each distinct letter in the word once
return len(vowels & letters) >= len(letters - vowels)
输出结果
['Our', 'to', 'we', 'about']
或者我们也可以计算单词中重复的字母:
def is_vowel_word_dups(word, vowels='aeiou'):
"""Whether half of the letters (counting duplicates) in a word are vowels.
"""
return 2*sum(c in vowels for c in word.lower()) >= len(word)
输出结果
['Our', 'to', 'we', 'become', 'about']
注意:后面的列表中有单词 'become'
,其中字母 e
出现了两次:这个单词有 2
个独特的元音('eo')和 3
个辅音('bcm'),所以它没有出现在第一个列表中。
这里有个有趣的版本,它计算单词中的元音 发音,而不是硬编码 'aeiou'
字母:
#!/usr/bin/env python
from nltk.corpus import cmudict # $ pip install nltk
# $ python -c "import nltk; nltk.download('cmudict')"
def is_vowel_word_snd(word, pronunciations=cmudict.dict()):
"""Whether a word pronunciation contains at least half vowel *sounds*."""
# check all pronuncations of the word
return any(2*sum(syl[-1].isdigit() for syl in syllables) >= len(syllables)
for syllables in pronunciations.get(word.lower(), []))
s = 'Our lives begin to end the day we become silent about things that matter'
words = s.split() # get whitespace-separated words
print([w for w in words if is_vowel_word_snd(w)])
输出结果
['Our', 'to', 'the', 'day', 'we', 'about', 'matter']
3
你的代码在处理每个字母时都把isvowel重置为零。你应该在第二个循环之前设置isvowel = 0
,而不是在之后。或者你可以用sum函数来简化你的代码:
def mostlyVowels(words):
vowel = {"A","e","E","i","I","o","O","u","U"}
final = []
for word in words.split():
if sum(x in vowel for x in word) >= len(word)/2:
final.append(word)
return final
2
我其实建议你可以不使用除法来做这个,算是对我上过的自动机理论课的一种致敬。在那门课上,我们用纸带来模拟跟踪符号:
def mostlyVowels(words):
acc = []
for word in words.split():
i = 0
for char in word.lower():
if char in 'aeiou': i += 1
else: i -= 1
if i > 0: acc.append(word)
return acc
一个非元音字母只是减少了一个词的“元音程度”,而这个程度的标准是1或更高 :P