Python:如何使用多个嵌套列表执行此列表理解?

时间:2015-12-20 00:50:21

标签: python list-comprehension

我正在处理我需要分解成一个句子标记列表的文本,这些标记本身被分解为单词标记。例如:

raw_text = "the cat in the hat.  green eggs and ham.  one fish two fish."

我还有一个要从文本中删除的停用词列表:

stopwords = ['the', 'and', 'in']

我正在使用nltk模块进行列表理解:

from nlkt import sent_tokenize, word_tokenize

sentence_tokens = [word_tokenize(sentence) for sentence in sent_tokenize(raw_text)]

这产生以下结果:

[['the', 'cat', 'in', 'the', 'hat', '.'], ['green', 'eggs', 'and', 'ham', '.'], ['one', 'fish', 'two', 'fish', '.']]

我可以使用嵌套for循环过滤掉停用词:

for sentences in sentence_tokens:
    for word in sentences:
        if word in stop:
            sentences.remove(word)

我遇到的麻烦是将这些全部合并到一个列表理解中,因此它更清洁一些。有什么建议?谢谢!

2 个答案:

答案 0 :(得分:1)

停用词设为set,然后您可以使用 list comp 过滤出停用词组中每个子列表中的字词:< / p>

stopwords = {'the', 'and', 'in'}


l = [['the', 'cat', 'in', 'the', 'hat', '.'], ['green', 'eggs', 'and', 'ham', '.'], ['one', 'fish', 'two', 'fish', '.']]


l[:] = [[word for word in sub if word not in stopwords] for sub in l]

输出:

[['cat', 'hat', '.'], ['green', 'eggs', 'ham', '.'], ['one', 'fish', 'two', 'fish', '.']]

使用l[:]意味着我们将改变原始对象/列表,如果我们将其分解为for循环:

# for each sublist in l
for sub in l:
    # for each word in the sublist, keep it only if it is not in stopwords 
    sub[:] =  [word for word in sub if word not in stopwords]

您自己的代码也有一个错误,您不应该通过删除元素来迭代和改变列表,您需要复制或者我们也可以使用reversed

for sentences in l:
    for word in reversed(sentences):
        if word in stopwords:
            sentences.remove(word)

当你从左边开始删除一个元素时,最终可能会删除错误的元素,因为当循环启动时某个指针指向的内容可能不一样,所以将来删除你可以删除错误的元素。 / p>

答案 1 :(得分:0)

提示:此任务不需要NLTK。一个简单的Python逻辑就可以了。 这是从文本中删除停用词的更简洁方法。我在这里使用Python 2.7。

如果需要字符串而不是单词列表:

raw_text = "the cat in the hat.  green eggs and ham.  one fish two fish."
stopwords = ['the', 'and', 'in']
clean_text = " ".join(word for word in raw_text.split() if word not in stopwords)

如果需要单词列表:

raw_text = "the cat in the hat.  green eggs and ham.  one fish two fish."
stopwords = ['the', 'and', 'in']
clean_list = [word for word in raw_text.split() if word not in stopwords]