【问题标题】:del doesnt seem to delete anything from a listdel 似乎没有从列表中删除任何内容
【发布时间】:2018-01-14 14:31:47
【问题描述】:
for x,y in words:
    for z in x:
        if z in stopwords:
            del x[x.index(z)]

这是我的代码。 words 中的数据是一个元组列表,其中元组如下所示:

(list of words, metadata)

我的代码的目的是从单词列表中删除所有停用词。 唯一的问题是,停用词之后不会被删除......

我到底做错了什么? 我已经尝试过使用

x.pop(x.index(z))

但这似乎没有什么不同。

【问题讨论】:

  • 在迭代时从列表中删除数据不是一个好主意,而且很可能会产生未定义的行为。相反,我会尝试将您的问题表述为列表理解,并创建一个符合您的标准的新列表。
  • 请举例说明单词和停用词

标签: python stop-words


【解决方案1】:

您可以使用嵌套列表推导简单地创建一个没有停用词的新列表:

stopwords = set(stopwords)  # just so "in" checks are faster
result = [([word for word in x if word not in stopwords], y) for x, y in words]

例如:

>>> stopwords = ['stop']
>>> words = [(['hello', 'you', 'stop'], 'somemeta')]
>>> stopwords = set(stopwords)  # just so "in" checks are faster
>>> result = [([word for word in x if word not in stopwords], y) for x, y in words]
>>> result
[(['hello', 'you'], 'somemeta')]

请注意,您通常不应修改您正在迭代的列表。这可能会导致很多难以追踪的错误。

【讨论】:

  • 您介意解释一下为什么要创建一组停用词吗?我不明白评论对不起
  • 成员资格测试的(平均)渐近运行时间对于集合是 O(1) - 对于列表和元组等其他容器,它是 O(n)(另见 wiki.python.org/moin/TimeComplexity)。尤其是因为 in 检查是在内循环中完成的,潜在的节省可能是巨大的。
【解决方案2】:
for x,y in words:
    for z in x:
        if z in stopwords:
            del x[x.index(z)]

最外面的循环将x 分配给您的单词列表之一。我们暂时忽略y。第二个循环遍历该单词列表; removing elements from a list you're iterating over causes peculiar behaviour。它可能会跳过特定的单词。这适用于所有的 del、pop、remove 和 slice 替换。

确保stopwordsset 并根据它过滤每个单词会更有效:x[:] = [w for w in x if w not in stopwords] 而不是那个内部循环。这里的切片替换纯粹是为了确保x 保持相同的对象,在这种情况下确保words 中的条目发生变化。 这不会遇到提到的迭代问题,因为列表推导在分配将其存储到切片之前构建其列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 2021-05-07
    • 1970-01-01
    • 1970-01-01
    • 2015-05-13
    相关资源
    最近更新 更多