判断一个单词中一半的字母是否是元音

2 投票
8 回答
711 浏览
提问于 2025-04-29 09:31

就像标题所说的,我想知道一个单词中的元音字母是否至少占字母总数的一半。

这是我的代码:

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

撰写回答