如果单词小于 X,则在列表理解中进行词形还原

Lemmatizing in a list comprehension if word is less than X

我有以下功能,它接收单词标记列表,以 WordNet 可读的格式收集词性标记,并使用它来对每个标记进行词形还原——我将它应用于列表列表单词标记:

from nltk import pos_tag
from nltk.stem import WordNetLemmatizer
from nltk.corpus import wordnet as wn

def getWordNetPOS (POStag):
    def is_noun(POStag):
        return POStag in ['NN', 'NNS', 'NNP', 'NNPS']
    def is_verb(POStag):
        return POStag in ['VB', 'VBD', 'VBG', 'VBN', 'VBP', 'VBZ']
    def is_adverb(POStag):
        return POStag in ['RB', 'RBR', 'RBS']
    def is_adjective(POStag):
        return POStag in ['JJ', 'JJR', 'JJS']

    if is_noun(POStag):
        return wn.NOUN
    elif is_verb(POStag):
        return wn.VERB
    elif is_adverb(POStag):
        return wn.ADV
    elif is_adjective(POStag):
        return wn.ADJ
    else:
        # if not noun, verb, adverb or adjective, return noun
        return wn.NOUN

# lemmatize word tokens
def lemmas (wordtokens):
    lemmatizer = WordNetLemmatizer()
    POStag = pos_tag(wordtokens)
    wordtokens = [lemmatizer.lemmatize(token[0], getWordNetPOS(token[1]))
                  for token in POStag]

    return wordtokens

lemmatizedList = []
mylist = [['this','is','my','first','sublist'],['this','is','my','second','sublist']]

for ls in mylist:
    x = lemmas(ls)
    lemmatizedList.append(x)

我想找到一种方法将词形还原限制为设定长度(即 2)的标记,但至关重要的是我还想保留任何小于此阈值的单词的原始形式。我得到的最接近的是将 if len(token[0])>2 添加到 lemmas 函数内的 wordtokens 列表理解的末尾,但这只是 returns 词形化标记。同样,我试图在 if 语句之后添加类似于 else token for token in POStag 的内容,但出现语法错误。为了清楚起见,这就是我的意思:

wordtokens = [lemmatizer.lemmatize(token[0], getWordNetPOS(token[1]))
              for token in POStag if len(token[0])>2
              else token for token in POStag]

我希望这是一个简单的错误,并且是我的 python 盲点。

这真的只是一个'blind spot'。

您必须稍微重构列表理解和条件:

wordtokens = [lemmatizer.lemmatize(token[0], getWordNetPOS(token[1])) if len(token[0]) > 2 else token
              for token in POStag]

解释:

列表推导式必须保留所有标记,因此您不想添加带有 if 的条件。

wordtokens = [<tokenoperation> for token in POStag]

现在,你想改变基于token长度的操作,所以你只改变tokenoperation的部分,这样它只修改token:

lemmatizer.lemmatize(token[0], getWordNetPOS(token[1])) if len(token[0]) > 2 else token

你也可以像这样添加一些括号,以使其更清楚:

wordtokens = [
    (
        lemmatizer.lemmatize(token[0], getWordNetPOS(token[1]))
        if len(token[0]) > 2
        else token
    )
    for token in POStag
]

一些 documentation/examples:请参阅此 realpython.com 页面上的 使用条件逻辑 部分。