产生名词的复数形式

2024-09-28 20:49:53 发布

您现在位置:Python中文网/ 问答频道 /正文

给定一个单词,它可能是单数形式的名词,也可能不是单数形式的名词,你如何生成它的复数形式?

基于这个NLTK tutorial和这个informal list关于多元化规则,我编写了这个简单的函数:

def plural(word):
    """
    Converts a word to its plural form.
    """
    if word in c.PLURALE_TANTUMS:
        # defective nouns, fish, deer, etc
        return word
    elif word in c.IRREGULAR_NOUNS:
        # foot->feet, person->people, etc
        return c.IRREGULAR_NOUNS[word]
    elif word.endswith('fe'):
        # wolf -> wolves
        return word[:-2] + 'ves'
    elif word.endswith('f'):
        # knife -> knives
        return word[:-1] + 'ves'
    elif word.endswith('o'):
        # potato -> potatoes
        return word + 'es'
    elif word.endswith('us'):
        # cactus -> cacti
        return word[:-2] + 'i'
    elif word.endswith('on'):
        # criterion -> criteria
        return word[:-2] + 'a'
    elif word.endswith('y'):
        # community -> communities
        return word[:-1] + 'ies'
    elif word[-1] in 'sx' or word[-2:] in ['sh', 'ch']:
        return word + 'es'
    elif word.endswith('an'):
        return word[:-2] + 'en'
    else:
        return word + 's'

但我认为这是不完整的。有更好的办法吗?


Tags: inreturnesetc单词形式wordelif
3条回答

首先,值得注意的是,正如the FAQ所解释的,WordNet不能生成复数形式。

如果你想用它,你可以。有了Morphy,WordNet也许能够为许多名词生成复数……但它仍然无法帮助处理大多数不规则名词,比如“children”。


无论如何,从Python使用WordNet的简单方法是通过NLTK。NLTK HOWTO文档之一解释了WordNet Interface。(当然,只使用NLTK而不指定语料库更容易,但这不是您所要求的。)

有一个较低级别的API到WordNet,称为^ {A4},但我相信它不再被维护(它成为NLTK集成的基础),只适用于Python的旧版本(可能是2.7,但不是3。x)和WordNet(只有2。x)。

或者,您可以始终使用ctypescffi或构建自定义绑定来访问C API,或者使用Jython而不是CPython来访问Java API。

当然,也可以通过subprocess调用命令行接口。


无论如何,至少在某些设备上,如果给简单的Morphy接口一个单数名词,它将返回其复数,而如果给它一个复数名词,它将返回其单数。所以:

from nltk.corpus import wordnet as wn
assert wn.morphy('dogs') == 'dog'
assert wn.morphy('dog') == 'dog'

事实上,这并没有被记录下来,甚至没有被暗示,这是真的,而且事实上,这对于OP来说显然不是真的,所以我不确定我是否想依赖它(即使它碰巧在你的电脑上工作)。

另一种方法是文档化,这样您可以编写一些应用所有可能的英语复数规则的规则,对每个规则调用morphy,第一个返回起始字符串的是正确的复数。

然而,文档化的工作方式是盲目地应用同样的规则。例如,它会正确地告诉你doges不是dog的复数形式,但不是因为它知道dogs是正确的答案;只是因为它知道doge是一个不同的词,它更喜欢“+s”规则而不是“+es”规则。所以,这不会有帮助。

此外,如上所述,它没有规则来处理任何不规则复数词WordNet不知道childrenchild以任何方式相关。

此外,wn.morphy('reckless')将返回'reckless',而不是None。如果你想要,你必须先测试它是不是一个名词。你只需使用相同的界面就可以做到这一点,尽管它有点老套:

def plural(word):
    result = wn.morphy(word)
    noun = wn.morphy(word, wn.NOUN)
    if noun in (word, result):
        return result

要正确地做到这一点,您实际上需要添加一个复数数据库,而不是试图欺骗WordNet做一些它做不到的事情。

此外,一个词可以有多个含义,它们可以有不同的复数,有时甚至有多个复数用于相同的含义。所以你可能想从(lemma for s in synsets(word, wn.NOUN) for lemma in s.lemmas if lemma.name == word)开始,然后得到所有合适的复数,而不是仅仅返回“the”复数。

模式en包(对于python 2.5+,但还不是python 3)提供了pluralization

>>> import pattern.en
>>> pattern.en.pluralize("dog")
'dogs'
>>> 

另一个支持python 3的选项是Inflect

import inflect
engine = inflect.engine()
plural = engine.plural(your_string)

相关问题 更多 >