【问题标题】:Converting a loop into a list comprehension to get IndexError: list index out of range将循环转换为列表推导以获取 IndexError: list index out of range
【发布时间】:2020-12-13 08:59:07
【问题描述】:

我想了解列表推导在此处的工作原理。

我有这个循环,它可以工作。


    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)> 就像我在类似问题中看到的那样,但它没有帮助.. 谢谢。

【问题讨论】:

  • 转换它时,你永远不会初始化s。所以这就是你得到错误的原因。
  • 不,即使我在 [...] 之前添加 s = wn.synsets(w, convert_tag(p)) 也不起作用。你可以运行我的代码。
  • 是的,当你像这样添加它时,它会弄乱语法。我只是告诉你什么是坏的。顺便说一句,如果您想使用列表理解,解决方法是根本不使用 s。这样想,原代码中的 s 怎么去掉?
  • 就这样吗? nsets = [(w, convert_tag(p))[0] for w, p in pos]
  • 多么简单!我很高兴你给了我一个提示而不是直接的答案。谢谢

标签: python-3.x for-loop indexing list-comprehension tokenize


【解决方案1】:

如果你绝对想在这里使用列表推导。 您需要修复如何从不声明 s。在这种情况下也没有很好的方法来声明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)) 来获得更快的代码? 通常在总体方案中,单个额外的临时变量是更好的选择,因为它具有定义的足迹,而双函数调用将具有指数规模。

【讨论】:

  • 好的,因为循环和列表理解给了我不同的答案..应该是这个 [Synset('tom.n.01'), Synset('love.v.01') , Synset('play.v.01')] 到 '汤姆喜欢玩滚球'。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 嗯,它看起来确实像海象! :O)
    猜你喜欢
    • 1970-01-01
    • 2015-02-11
    • 2019-02-23
    • 1970-01-01
    • 1970-01-01
    • 2022-11-18
    • 2018-02-08
    • 2014-10-20
    • 1970-01-01
    相关资源
    最近更新 更多