del似乎没有从列表中删除任何东西

问题描述:

for x,y in words: 
    for z in x: 
     if z in stopwords: 
      del x[x.index(z)] 

这是我的代码。在字的数据是元组的列表,其中一个元组看起来是这样的:del似乎没有从列表中删除任何东西

(list of words, metadata) 

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

我究竟做错了什么? 我已经尝试过用

x.pop(x.index(z)) 

做到这一点,但似乎不有所作为。

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')] 

请注意,您一般不应该修改的列表,你”

+3

迭代时从列表中删除数据不是一个好主意,并且很可能会产生未定义的行为。相反,我会尝试将您的问题列为理解,并创建一个符合您的标准的新列表。 –

+0

请给出一个单词和停用词的例子 – nacho

你可以使用嵌套列表理解简单地创建一个没有停止的话一个新的列表重新迭代。这可能导致很多难以追踪的错误。

+0

你会介意解释为什么你创建一组停用词吗?我不明白意见对不起 – DrBwts

+2

成员测试的(平均)渐近运行时对于集合是'O(1)' - 对于其他容器,如列表和元组,它是'O(n)'(另见https:// wiki。 python.org/moin/TimeComplexity)。特别是因为'in'检查是在内部循环中完成的,潜在的节约可能是巨大的。 – MSeifert

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内的条目发生更改。 这不会遇到上述迭代问题,因为列表理解在分配将其存储到片中之前构建其列表。