Converting a loop into a list comprehension to get IndexError: list index out of range

Converting a loop into a list comprehension to get IndexError: list index out of range

我想了解列表推导在这里是如何工作的。

我有这个循环并且它有效。


    token = nltk.word_tokenize(doc)
    # add parts of speech to token
    pos = nltk.pos_tag(token)
    nsets = []
    for w, p in pos:
        s = wn.synsets(w, convert_tag(p))
        if s:
            nsets.append(s[0])
        else:
            continue

然而,当我尝试像这样进行列表理解时

nsets = [s[0] for w, p in pos if s == wn.synsets(w, convert_tag(p))]

我明白了

IndexError                                Traceback (most recent call last)
<ipython-input-26-406837792edd> in <module>()
----> 1 doc_to_synsets('Tom loves to play petanque')

<ipython-input-25-1eca09bded8e> in doc_to_synsets(doc)
     44             continue
     45 
---> 46     nsets = [s[0] for w, p in pos if s == wn.synsets(w, convert_tag(p))]
     47 
     48     nltk2wordnet = [(i[0], convert_tag(i[1])) for i in pos]

<ipython-input-25-1eca09bded8e> in <listcomp>(.0)
     44             continue
     45 
---> 46     nsets = [s[0] for w, p in pos if s == wn.synsets(w, convert_tag(p))]
     47 
     48     nltk2wordnet = [(i[0], convert_tag(i[1])) for i in pos]

IndexError: list index out of range

我试过在列表的末尾添加 len(s[0])>0 和 len(s)> 就像我在类似问题中看到的那样,但它没有帮助.. 谢谢。

所有列表索引都从 0 开始,因此如果列表中有 23 个项目,则最后一个项目是项目 # 22。

如果你绝对想在这里使用列表理解。 您需要修复从未声明 [​​=11=] 的方式。在这种情况下也没有好的方法来声明 s,所以你必须调用 wn.synsets(w, convert_tag(p)) 两次。

synsets = [wn.synsets(w, convert_tag(p))[0] for w, p in pos if wn.synsets(w, convert_tag(p))]

但是由于您两次调用同一个函数,列表理解会比原始代码慢。

问题就变成了,您是想通过从不声明 s 来节省内存,还是希望通过只需要 运行 wn.synsets(w, convert_tag(p)) 一次来加快代码速度? 通常在宏伟的计划中,单个额外的临时变量是更好的选择,因为它具有定义的占用空间,而双函数调用将具有指数级。

Python 3.8起,您可以使用海象运算符(:=):

nsets = [s[0] for w, p in pos if (s := wn.synsets(w, convert_tag(p)))]